1/* 2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of 3 * British Columbia. 4 * Copyright (c) 2001-2002 Michael David Adams. 5 * All rights reserved. 6 */ 7 8/* __START_OF_JASPER_LICENSE__ 9 * 10 * JasPer Software License 11 * 12 * IMAGE POWER JPEG-2000 PUBLIC LICENSE 13 * ************************************ 14 * 15 * GRANT: 16 * 17 * Permission is hereby granted, free of charge, to any person (the "User") 18 * obtaining a copy of this software and associated documentation, to deal 19 * in the JasPer Software without restriction, including without limitation 20 * the right to use, copy, modify, merge, publish, distribute, sublicense, 21 * and/or sell copies of the JasPer Software (in source and binary forms), 22 * and to permit persons to whom the JasPer Software is furnished to do so, 23 * provided further that the License Conditions below are met. 24 * 25 * License Conditions 26 * ****************** 27 * 28 * A. Redistributions of source code must retain the above copyright notice, 29 * and this list of conditions, and the following disclaimer. 30 * 31 * B. Redistributions in binary form must reproduce the above copyright 32 * notice, and this list of conditions, and the following disclaimer in 33 * the documentation and/or other materials provided with the distribution. 34 * 35 * C. Neither the name of Image Power, Inc. nor any other contributor 36 * (including, but not limited to, the University of British Columbia and 37 * Michael David Adams) may be used to endorse or promote products derived 38 * from this software without specific prior written permission. 39 * 40 * D. User agrees that it shall not commence any action against Image Power, 41 * Inc., the University of British Columbia, Michael David Adams, or any 42 * other contributors (collectively "Licensors") for infringement of any 43 * intellectual property rights ("IPR") held by the User in respect of any 44 * technology that User owns or has a right to license or sublicense and 45 * which is an element required in order to claim compliance with ISO/IEC 46 * 15444-1 (i.e., JPEG-2000 Part 1). "IPR" means all intellectual property 47 * rights worldwide arising under statutory or common law, and whether 48 * or not perfected, including, without limitation, all (i) patents and 49 * patent applications owned or licensable by User; (ii) rights associated 50 * with works of authorship including copyrights, copyright applications, 51 * copyright registrations, mask work rights, mask work applications, 52 * mask work registrations; (iii) rights relating to the protection of 53 * trade secrets and confidential information; (iv) any right analogous 54 * to those set forth in subsections (i), (ii), or (iii) and any other 55 * proprietary rights relating to intangible property (other than trademark, 56 * trade dress, or service mark rights); and (v) divisions, continuations, 57 * renewals, reissues and extensions of the foregoing (as and to the extent 58 * applicable) now existing, hereafter filed, issued or acquired. 59 * 60 * E. If User commences an infringement action against any Licensor(s) then 61 * such Licensor(s) shall have the right to terminate User's license and 62 * all sublicenses that have been granted hereunder by User to other parties. 63 * 64 * F. This software is for use only in hardware or software products that 65 * are compliant with ISO/IEC 15444-1 (i.e., JPEG-2000 Part 1). No license 66 * or right to this Software is granted for products that do not comply 67 * with ISO/IEC 15444-1. The JPEG-2000 Part 1 standard can be purchased 68 * from the ISO. 69 * 70 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. 71 * NO USE OF THE JASPER SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER 72 * THIS DISCLAIMER. THE JASPER SOFTWARE IS PROVIDED BY THE LICENSORS AND 73 * CONTRIBUTORS UNDER THIS LICENSE ON AN ``AS-IS'' BASIS, WITHOUT WARRANTY 74 * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 75 * WARRANTIES THAT THE JASPER SOFTWARE IS FREE OF DEFECTS, IS MERCHANTABLE, 76 * IS FIT FOR A PARTICULAR PURPOSE OR IS NON-INFRINGING. THOSE INTENDING 77 * TO USE THE JASPER SOFTWARE OR MODIFICATIONS THEREOF FOR USE IN HARDWARE 78 * OR SOFTWARE PRODUCTS ARE ADVISED THAT THEIR USE MAY INFRINGE EXISTING 79 * PATENTS, COPYRIGHTS, TRADEMARKS, OR OTHER INTELLECTUAL PROPERTY RIGHTS. 80 * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE JASPER SOFTWARE 81 * IS WITH THE USER. SHOULD ANY PART OF THE JASPER SOFTWARE PROVE DEFECTIVE 82 * IN ANY RESPECT, THE USER (AND NOT THE INITIAL DEVELOPERS, THE UNIVERSITY 83 * OF BRITISH COLUMBIA, IMAGE POWER, INC., MICHAEL DAVID ADAMS, OR ANY 84 * OTHER CONTRIBUTOR) SHALL ASSUME THE COST OF ANY NECESSARY SERVICING, 85 * REPAIR OR CORRECTION. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, 86 * WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE 87 * INITIAL DEVELOPER, THE UNIVERSITY OF BRITISH COLUMBIA, IMAGE POWER, INC., 88 * MICHAEL DAVID ADAMS, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF THE 89 * JASPER SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO 90 * THE USER OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR 91 * CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, 92 * DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR 93 * MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF 94 * SUCH PARTY HAD BEEN INFORMED, OR OUGHT TO HAVE KNOWN, OF THE POSSIBILITY 95 * OF SUCH DAMAGES. THE JASPER SOFTWARE AND UNDERLYING TECHNOLOGY ARE NOT 96 * FAULT-TOLERANT AND ARE NOT DESIGNED, MANUFACTURED OR INTENDED FOR USE OR 97 * RESALE AS ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING 98 * FAIL-SAFE PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, 99 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT 100 * LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE 101 * JASPER SOFTWARE OR UNDERLYING TECHNOLOGY OR PRODUCT COULD LEAD DIRECTLY 102 * TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE 103 * ("HIGH RISK ACTIVITIES"). LICENSOR SPECIFICALLY DISCLAIMS ANY EXPRESS 104 * OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. USER WILL NOT 105 * KNOWINGLY USE, DISTRIBUTE OR RESELL THE JASPER SOFTWARE OR UNDERLYING 106 * TECHNOLOGY OR PRODUCTS FOR HIGH RISK ACTIVITIES AND WILL ENSURE THAT ITS 107 * CUSTOMERS AND END-USERS OF ITS PRODUCTS ARE PROVIDED WITH A COPY OF THE 108 * NOTICE SPECIFIED IN THIS SECTION. 109 * 110 * __END_OF_JASPER_LICENSE__ 111 */ 112 113/* 114 * Image Library 115 * 116 * $Id: jas_image.c 14449 2005-10-20 12:15:56Z stippi $ 117 */ 118 119/******************************************************************************\ 120* Includes. 121\******************************************************************************/ 122 123#include <stdlib.h> 124#include <stdio.h> 125#include <string.h> 126#include <assert.h> 127#include <ctype.h> 128 129#include "jasper/jas_math.h" 130#include "jasper/jas_image.h" 131#include "jasper/jas_malloc.h" 132#include "jasper/jas_string.h" 133 134/******************************************************************************\ 135* Types. 136\******************************************************************************/ 137 138/******************************************************************************\ 139* Local prototypes. 140\******************************************************************************/ 141 142static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt); 143static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly, 144 uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t 145 height, uint_fast16_t depth, JPR_BOOL sgnd, uint_fast32_t inmem); 146static void jas_image_setbbox(jas_image_t *image); 147static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt); 148static jas_image_cmpt_t *jas_image_cmpt_create0(); 149static int jas_image_growcmpts(jas_image_t *image, int maxcmpts); 150static uint_fast32_t inttobits(jas_seqent_t v, int prec, JPR_BOOL sgnd); 151static jas_seqent_t bitstoint(uint_fast32_t v, int prec, JPR_BOOL sgnd); 152 153/******************************************************************************\ 154* Global data. 155\******************************************************************************/ 156 157static int jas_image_numfmts = 0; 158static jas_image_fmtinfo_t jas_image_fmtinfos[JAS_IMAGE_MAXFMTS]; 159 160/******************************************************************************\ 161* Create and destroy operations. 162\******************************************************************************/ 163 164jas_image_t *jas_image_create(uint_fast16_t numcmpts, jas_image_cmptparm_t *cmptparms, 165 int colorspace) 166{ 167 jas_image_t *image; 168 uint_fast32_t rawsize; 169 uint_fast32_t inmem; 170 uint_fast16_t cmptno; 171 jas_image_cmptparm_t *cmptparm; 172 173 if (!(image = jas_image_create0())) { 174 return 0; 175 } 176 177 image->colorspace_ = colorspace; 178 image->maxcmpts_ = numcmpts; 179 image->inmem_ = JPR_TRUE; 180 181 /* Allocate memory for the per-component information. */ 182 if (!(image->cmpts_ = jas_malloc(image->maxcmpts_ * 183 sizeof(jas_image_cmpt_t *)))) { 184 jas_image_destroy(image); 185 return 0; 186 } 187 /* Initialize in case of failure. */ 188 for (cmptno = 0; cmptno < image->maxcmpts_; ++cmptno) { 189 image->cmpts_[cmptno] = 0; 190 } 191 192 /* Compute the approximate raw size of the image. */ 193 rawsize = 0; 194 for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, 195 ++cmptparm) { 196 rawsize += cmptparm->width * cmptparm->height * 197 (cmptparm->prec + 7) / 8; 198 } 199 /* Decide whether to buffer the image data in memory, based on the 200 raw size of the image. */ 201 inmem = (rawsize < JAS_IMAGE_INMEMTHRESH); 202 203 /* Create the individual image components. */ 204 for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, 205 ++cmptparm) { 206 if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx, 207 cmptparm->tly, cmptparm->hstep, cmptparm->vstep, 208 cmptparm->width, cmptparm->height, cmptparm->prec, 209 cmptparm->sgnd, inmem))) { 210 jas_image_destroy(image); 211 return 0; 212 } 213 ++image->numcmpts_; 214 } 215 216 /* Determine the bounding box for all of the components on the 217 reference grid (i.e., the image area) */ 218 jas_image_setbbox(image); 219 220 return image; 221} 222 223jas_image_t *jas_image_create0() 224{ 225 jas_image_t *image; 226 227 if (!(image = jas_malloc(sizeof(jas_image_t)))) { 228 return 0; 229 } 230 231 image->tlx_ = 0; 232 image->tly_ = 0; 233 image->brx_ = 0; 234 image->bry_ = 0; 235 image->colorspace_ = JAS_IMAGE_CS_UNKNOWN; 236 image->numcmpts_ = 0; 237 image->maxcmpts_ = 0; 238 image->cmpts_ = 0; 239 image->inmem_ = JPR_TRUE; 240 image->iccp_ = 0; 241 image->iccplen_ = 0; 242 243 return image; 244} 245 246jas_image_t *jas_image_copy(jas_image_t *image) 247{ 248 jas_image_t *newimage; 249 int cmptno; 250 251 newimage = jas_image_create0(); 252 if (jas_image_growcmpts(newimage, image->numcmpts_)) { 253 goto error; 254 } 255 for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { 256 if (!(newimage->cmpts_[cmptno] = jas_image_cmpt_copy(image->cmpts_[cmptno]))) { 257 goto error; 258 } 259 ++newimage->numcmpts_; 260 } 261 262 jas_image_setbbox(newimage); 263 264 return newimage; 265error: 266 if (newimage) { 267 jas_image_destroy(newimage); 268 } 269 return 0; 270} 271 272static jas_image_cmpt_t *jas_image_cmpt_create0() 273{ 274 jas_image_cmpt_t *cmpt; 275 if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) { 276 return 0; 277 } 278 memset(cmpt, 0, sizeof(jas_image_cmpt_t)); 279 cmpt->type_ = JAS_IMAGE_CT_UNKNOWN; 280 return cmpt; 281} 282 283static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt) 284{ 285 jas_image_cmpt_t *newcmpt; 286 287 if (!(newcmpt = jas_image_cmpt_create0())) { 288 return 0; 289 } 290 newcmpt->tlx_ = cmpt->tlx_; 291 newcmpt->tly_ = cmpt->tly_; 292 newcmpt->hstep_ = cmpt->hstep_; 293 newcmpt->vstep_ = cmpt->vstep_; 294 newcmpt->width_ = cmpt->width_; 295 newcmpt->height_ = cmpt->height_; 296 newcmpt->prec_ = cmpt->prec_; 297 newcmpt->sgnd_ = cmpt->sgnd_; 298 newcmpt->cps_ = cmpt->cps_; 299 newcmpt->type_ = cmpt->type_; 300 if (!(newcmpt->stream_ = jas_stream_memopen(0, 0))) { 301 return 0; 302 } 303 if (jas_stream_seek(cmpt->stream_, 0, SEEK_SET)) { 304 return 0; 305 } 306 if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) { 307 return 0; 308 } 309 if (jas_stream_seek(newcmpt->stream_, 0, SEEK_SET)) { 310 return 0; 311 } 312 return newcmpt; 313} 314 315void jas_image_destroy(jas_image_t *image) 316{ 317 int i; 318 319 if (image->cmpts_) { 320 for (i = 0; i < image->numcmpts_; ++i) { 321 jas_image_cmpt_destroy(image->cmpts_[i]); 322 image->cmpts_[i] = 0; 323 } 324 jas_free(image->cmpts_); 325 } 326 jas_free(image); 327} 328 329static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly, 330 uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t 331 height, uint_fast16_t depth, JPR_BOOL sgnd, uint_fast32_t inmem) 332{ 333 jas_image_cmpt_t *cmpt; 334 long size; 335 336 if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) { 337 return 0; 338 } 339 340 cmpt->tlx_ = tlx; 341 cmpt->tly_ = tly; 342 cmpt->hstep_ = hstep; 343 cmpt->vstep_ = vstep; 344 cmpt->width_ = width; 345 cmpt->height_ = height; 346 cmpt->prec_ = depth; 347 cmpt->sgnd_ = sgnd; 348 cmpt->stream_ = 0; 349 cmpt->cps_ = (depth + 7) / 8; 350 351 size = cmpt->width_ * cmpt->height_ * cmpt->cps_; 352 cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) : jas_stream_tmpfile(); 353 if (!cmpt->stream_) { 354 jas_image_cmpt_destroy(cmpt); 355 return 0; 356 } 357 358 /* Zero the component data. This isn't necessary, but it is 359 convenient for debugging purposes. */ 360 if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 || 361 jas_stream_putc(cmpt->stream_, 0) == EOF || 362 jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) { 363 jas_image_cmpt_destroy(cmpt); 364 return 0; 365 } 366 367 return cmpt; 368} 369 370static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt) 371{ 372 if (cmpt->stream_) { 373 jas_stream_close(cmpt->stream_); 374 } 375 jas_free(cmpt); 376} 377 378/******************************************************************************\ 379* Load and save operations. 380\******************************************************************************/ 381 382jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr) 383{ 384 jas_image_fmtinfo_t *fmtinfo; 385 386 /* If possible, try to determine the format of the input data. */ 387 if (fmt < 0) { 388 if ((fmt = jas_image_getfmt(in)) < 0) { 389 return 0; 390 } 391 } 392 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { 393 return 0; 394 } 395 return (fmtinfo->ops.decode) ? (*fmtinfo->ops.decode)(in, optstr) : 0; 396} 397 398int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, char *optstr) 399{ 400 jas_image_fmtinfo_t *fmtinfo; 401 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { 402 return -1; 403 } 404 return (fmtinfo->ops.encode) ? (*fmtinfo->ops.encode)(image, out, 405 optstr) : (-1); 406} 407 408/******************************************************************************\ 409* Component read and write operations. 410\******************************************************************************/ 411 412int jas_image_readcmpt(jas_image_t *image, uint_fast16_t cmptno, uint_fast32_t x, uint_fast32_t y, uint_fast32_t width, 413 uint_fast32_t height, jas_matrix_t *data) 414{ 415 jas_image_cmpt_t *cmpt; 416 uint_fast32_t i; 417 uint_fast32_t j; 418 int k; 419 jas_seqent_t v; 420 int c; 421 jas_seqent_t *dr; 422 jas_seqent_t *d; 423 int drs; 424 425 if (cmptno < 0 || cmptno >= image->numcmpts_) { 426 return -1; 427 } 428 429 cmpt = image->cmpts_[cmptno]; 430 if (x >= cmpt->width_ || y >= cmpt->height_ || 431 x + width > cmpt->width_ || 432 y + height > cmpt->height_) { 433 return -1; 434 } 435 436 if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) { 437 if (jas_matrix_resize(data, height, width)) { 438 return -1; 439 } 440 } 441 442 dr = jas_matrix_getref(data, 0, 0); 443 drs = jas_matrix_rowstep(data); 444 for (i = 0; i < height; ++i, dr += drs) { 445 d = dr; 446 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) 447 * cmpt->cps_, SEEK_SET) < 0) { 448 return -1; 449 } 450 for (j = width; j > 0; --j, ++d) { 451 v = 0; 452 for (k = cmpt->cps_; k > 0; --k) { 453 if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { 454 return -1; 455 } 456 v = (v << 8) | (c & 0xff); 457 } 458 *d = bitstoint(v, cmpt->prec_, cmpt->sgnd_); 459 } 460 } 461 462 return 0; 463} 464 465#if 0 466int_fast64_t jas_image_readcmpt1(jas_image_t *image, uint_fast16_t cmptno, 467 uint_fast32_t x, uint_fast32_t y) 468{ 469 jas_image_cmpt_t *cmpt; 470 int k; 471 int c; 472 int_fast64_t v; 473 cmpt = image->cmpts_[cmptno]; 474 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, 475 SEEK_SET) < 0) { 476 goto error; 477 } 478 v = 0; 479 for (k = cmpt->cps_; k > 0; --k) { 480 if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { 481 goto error; 482 } 483 v = (v << 8) | (c & 0xff); 484 } 485if (cmpt->sgnd_) { 486 abort(); 487} 488 489 return v; 490 491error: 492 return 0; 493} 494#endif 495 496int jas_image_writecmpt(jas_image_t *image, uint_fast16_t cmptno, uint_fast32_t x, uint_fast32_t y, uint_fast32_t width, 497 uint_fast32_t height, jas_matrix_t *data) 498{ 499 jas_image_cmpt_t *cmpt; 500 uint_fast32_t i; 501 uint_fast32_t j; 502 jas_seqent_t *d; 503 jas_seqent_t *dr; 504 int drs; 505 jas_seqent_t v; 506 int k; 507 int c; 508 509 if (cmptno < 0 || cmptno >= image->numcmpts_) { 510 return -1; 511 } 512 513 cmpt = image->cmpts_[cmptno]; 514 if (x >= cmpt->width_ || y >= cmpt->height_ || 515 x + width > cmpt->width_ || 516 y + height > cmpt->height_) { 517 return -1; 518 } 519 520 if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) { 521 return -1; 522 } 523 524 dr = jas_matrix_getref(data, 0, 0); 525 drs = jas_matrix_rowstep(data); 526 for (i = 0; i < height; ++i, dr += drs) { 527 d = dr; 528 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) 529 * cmpt->cps_, SEEK_SET) < 0) { 530 return -1; 531 } 532 for (j = width; j > 0; --j, ++d) { 533 v = inttobits(*d, cmpt->prec_, cmpt->sgnd_); 534 for (k = cmpt->cps_; k > 0; --k) { 535 c = (v >> (8 * (cmpt->cps_ - 1))) & 0xff; 536 if (jas_stream_putc(cmpt->stream_, 537 (unsigned char) c) == EOF) { 538 return -1; 539 } 540 v <<= 8; 541 } 542 } 543 } 544 545 return 0; 546} 547 548/******************************************************************************\ 549* File format operations. 550\******************************************************************************/ 551 552void jas_image_clearfmts() 553{ 554 int i; 555 jas_image_fmtinfo_t *fmtinfo; 556 for (i = 0; i < jas_image_numfmts; ++i) { 557 fmtinfo = &jas_image_fmtinfos[i]; 558 if (fmtinfo->name) { 559 jas_free(fmtinfo->name); 560 fmtinfo->name = 0; 561 } 562 if (fmtinfo->ext) { 563 jas_free(fmtinfo->ext); 564 fmtinfo->ext = 0; 565 } 566 if (fmtinfo->desc) { 567 jas_free(fmtinfo->desc); 568 fmtinfo->desc = 0; 569 } 570 } 571 jas_image_numfmts = 0; 572} 573 574int jas_image_addfmt(int id, char *name, char *ext, char *desc, 575 jas_image_fmtops_t *ops) 576{ 577 jas_image_fmtinfo_t *fmtinfo; 578 assert(id >= 0 && name && ext && ops); 579 if (jas_image_numfmts >= JAS_IMAGE_MAXFMTS) { 580 return -1; 581 } 582 fmtinfo = &jas_image_fmtinfos[jas_image_numfmts]; 583 fmtinfo->id = id; 584 if (!(fmtinfo->name = jas_strdup(name))) { 585 return -1; 586 } 587 if (!(fmtinfo->ext = jas_strdup(ext))) { 588 jas_free(fmtinfo->name); 589 return -1; 590 } 591 if (!(fmtinfo->desc = jas_strdup(desc))) { 592 jas_free(fmtinfo->name); 593 jas_free(fmtinfo->ext); 594 return -1; 595 } 596 fmtinfo->ops = *ops; 597 ++jas_image_numfmts; 598 return 0; 599} 600 601int jas_image_strtofmt(char *name) 602{ 603 jas_image_fmtinfo_t *fmtinfo; 604 if (!(fmtinfo = jas_image_lookupfmtbyname(name))) { 605 return -1; 606 } 607 return fmtinfo->id; 608} 609 610char *jas_image_fmttostr(int fmt) 611{ 612 jas_image_fmtinfo_t *fmtinfo; 613 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { 614 return 0; 615 } 616 return fmtinfo->name; 617} 618 619int jas_image_getfmt(jas_stream_t *in) 620{ 621 jas_image_fmtinfo_t *fmtinfo; 622 int found; 623 int i; 624 625 /* Check for data in each of the supported formats. */ 626 found = 0; 627 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, 628 ++fmtinfo) { 629 if (fmtinfo->ops.validate) { 630 /* Is the input data valid for this format? */ 631 if (!(*fmtinfo->ops.validate)(in)) { 632 found = 1; 633 break; 634 } 635 } 636 } 637 return found ? fmtinfo->id : (-1); 638} 639 640int jas_image_fmtfromname(char *name) 641{ 642 int i; 643 char *ext; 644 jas_image_fmtinfo_t *fmtinfo; 645 /* Get the file name extension. */ 646 if (!(ext = strrchr(name, '.'))) { 647 return -1; 648 } 649 ++ext; 650 /* Try to find a format that uses this extension. */ 651 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, 652 ++fmtinfo) { 653 /* Do we have a match? */ 654 if (!strcmp(ext, fmtinfo->ext)) { 655 return fmtinfo->id; 656 } 657 } 658 return -1; 659} 660 661/******************************************************************************\ 662* Miscellaneous operations. 663\******************************************************************************/ 664 665uint_fast32_t jas_image_rawsize(jas_image_t *image) 666{ 667 uint_fast32_t rawsize; 668 uint_fast32_t cmptno; 669 jas_image_cmpt_t *cmpt; 670 671 rawsize = 0; 672 for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { 673 cmpt = image->cmpts_[cmptno]; 674 rawsize += (cmpt->width_ * cmpt->height_ * cmpt->prec_ + 675 7) / 8; 676 } 677 return rawsize; 678} 679 680void jas_image_delcmpt(jas_image_t *image, uint_fast16_t cmptno) 681{ 682 if (cmptno >= image->numcmpts_) { 683 return; 684 } 685 jas_image_cmpt_destroy(image->cmpts_[cmptno]); 686 if (cmptno < image->numcmpts_) { 687 memmove(&image->cmpts_[cmptno], &image->cmpts_[cmptno + 1], 688 (image->numcmpts_ - 1 - cmptno) * sizeof(jas_image_cmpt_t *)); 689 } 690 --image->numcmpts_; 691 692 jas_image_setbbox(image); 693} 694 695int jas_image_addcmpt(jas_image_t *image, uint_fast16_t cmptno, 696 jas_image_cmptparm_t *cmptparm) 697{ 698 jas_image_cmpt_t *newcmpt; 699 assert(cmptno >= 0 && cmptno <= image->numcmpts_); 700 if (image->numcmpts_ >= image->maxcmpts_) { 701 if (jas_image_growcmpts(image, image->maxcmpts_ + 128)) { 702 return -1; 703 } 704 } 705 if (!(newcmpt = jas_image_cmpt_create(cmptparm->tlx, 706 cmptparm->tly, cmptparm->hstep, cmptparm->vstep, 707 cmptparm->width, cmptparm->height, cmptparm->prec, 708 cmptparm->sgnd, 1))) { 709 return -1; 710 } 711 if (cmptno < image->numcmpts_) { 712 memmove(&image->cmpts_[cmptno + 1], &image->cmpts_[cmptno], 713 (image->numcmpts_ - cmptno) * sizeof(jas_image_cmpt_t *)); 714 } 715 image->cmpts_[cmptno] = newcmpt; 716 ++image->numcmpts_; 717 718 jas_image_setbbox(image); 719 720 return 0; 721} 722 723jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id) 724{ 725 int i; 726 jas_image_fmtinfo_t *fmtinfo; 727 728 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) { 729 if (fmtinfo->id == id) { 730 return fmtinfo; 731 } 732 } 733 return 0; 734} 735 736jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name) 737{ 738 int i; 739 jas_image_fmtinfo_t *fmtinfo; 740 741 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) { 742 if (!strcmp(fmtinfo->name, name)) { 743 return fmtinfo; 744 } 745 } 746 return 0; 747} 748 749 750 751 752 753static uint_fast32_t inttobits(jas_seqent_t v, int prec, JPR_BOOL sgnd) 754{ 755 uint_fast32_t ret; 756 ret = ((sgnd && v < 0) ? ((1 << prec) + v) : v) & JAS_ONES(prec); 757 return ret; 758} 759 760static jas_seqent_t bitstoint(uint_fast32_t v, int prec, JPR_BOOL sgnd) 761{ 762 jas_seqent_t ret; 763 v &= JAS_ONES(prec); 764 ret = (sgnd && (v & (1 << (prec - 1)))) ? (v - (1 << prec)) : v; 765 return ret; 766} 767 768static void jas_image_setbbox(jas_image_t *image) 769{ 770 jas_image_cmpt_t *cmpt; 771 int cmptno; 772 int_fast32_t x; 773 int_fast32_t y; 774 775 if (image->numcmpts_ > 0) { 776 /* Determine the bounding box for all of the components on the 777 reference grid (i.e., the image area) */ 778 cmpt = image->cmpts_[0]; 779 image->tlx_ = cmpt->tlx_; 780 image->tly_ = cmpt->tly_; 781 image->brx_ = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1; 782 image->bry_ = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1; 783 for (cmptno = 1; cmptno < image->numcmpts_; ++cmptno) { 784 cmpt = image->cmpts_[cmptno]; 785 if (image->tlx_ > cmpt->tlx_) { 786 image->tlx_ = cmpt->tlx_; 787 } 788 if (image->tly_ > cmpt->tly_) { 789 image->tly_ = cmpt->tly_; 790 } 791 x = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1; 792 if (image->brx_ < x) { 793 image->brx_ = x; 794 } 795 y = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1; 796 if (image->bry_ < y) { 797 image->bry_ = y; 798 } 799 } 800 } else { 801 image->tlx_ = 0; 802 image->tly_ = 0; 803 image->brx_ = 0; 804 image->bry_ = 0; 805 } 806} 807 808static int jas_image_growcmpts(jas_image_t *image, int maxcmpts) 809{ 810 jas_image_cmpt_t **newcmpts; 811 int cmptno; 812 813 newcmpts = (!image->cmpts_) ? jas_malloc(maxcmpts * sizeof(jas_image_cmpt_t *)) : 814 jas_realloc(image->cmpts_, maxcmpts * sizeof(jas_image_cmpt_t *)); 815 if (!newcmpts) { 816 return -1; 817 } 818 image->cmpts_ = newcmpts; 819 image->maxcmpts_ = maxcmpts; 820 for (cmptno = image->numcmpts_; cmptno < image->maxcmpts_; ++cmptno) { 821 image->cmpts_[cmptno] = 0; 822 } 823 return 0; 824} 825 826int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno, jas_image_t *srcimage, 827 int srccmptno) 828{ 829 jas_image_cmpt_t *newcmpt; 830 if (dstimage->numcmpts_ >= dstimage->maxcmpts_) { 831 if (jas_image_growcmpts(dstimage, dstimage->maxcmpts_ + 128)) { 832 return -1; 833 } 834 } 835 if (!(newcmpt = jas_image_cmpt_copy(srcimage->cmpts_[srccmptno]))) { 836 return -1; 837 } 838 if (dstcmptno < dstimage->numcmpts_) { 839 memmove(&dstimage->cmpts_[dstcmptno + 1], &dstimage->cmpts_[dstcmptno], 840 (dstimage->numcmpts_ - dstcmptno) * sizeof(jas_image_cmpt_t *)); 841 } 842 dstimage->cmpts_[dstcmptno] = newcmpt; 843 ++dstimage->numcmpts_; 844 845 jas_image_setbbox(dstimage); 846 return 0; 847} 848 849void jas_image_dump(jas_image_t *image, FILE *out) 850{ 851 int cmptno; 852 jas_seq2d_t *data; 853 jas_image_cmpt_t *cmpt; 854 if (!(data = jas_seq2d_create(0, 0, 1, 1))) { 855 abort(); 856 } 857 for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { 858 cmpt = image->cmpts_[cmptno]; 859 fprintf(out, "prec=%d sgnd=%d\n", cmpt->prec_, cmpt->sgnd_); 860 if (jas_image_readcmpt(image, cmptno, 0, 0, 1, 1, data)) { 861 abort(); 862 } 863 fprintf(out, "tlsample %ld\n", (long) jas_seq2d_get(data, 0, 0)); 864 } 865 jas_seq2d_destroy(data); 866} 867 868int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents, 869 int_fast32_t *lutents, int dtype, int newcmptno) 870{ 871 jas_image_cmptparm_t cmptparms; 872 int_fast32_t v; 873 int i; 874 int j; 875 jas_image_cmpt_t *cmpt; 876 877 cmpt = image->cmpts_[cmptno]; 878 cmptparms.tlx = cmpt->tlx_; 879 cmptparms.tly = cmpt->tly_; 880 cmptparms.hstep = cmpt->hstep_; 881 cmptparms.vstep = cmpt->vstep_; 882 cmptparms.width = cmpt->width_; 883 cmptparms.height = cmpt->height_; 884 cmptparms.prec = JAS_IMAGE_CDT_GETPREC(dtype); 885 cmptparms.sgnd = JAS_IMAGE_CDT_GETSGND(dtype); 886 887 if (jas_image_addcmpt(image, newcmptno, &cmptparms)) { 888 return -1; 889 } 890 if (newcmptno <= cmptno) { 891 ++cmptno; 892 cmpt = image->cmpts_[cmptno]; 893 } 894 895 for (j = 0; j < cmpt->height_; ++j) { 896 for (i = 0; i < cmpt->width_; ++i) { 897 v = jas_image_readcmptsample(image, cmptno, i, j); 898 if (v < 0) { 899 v = 0; 900 } else if (v >= numlutents) { 901 v = numlutents - 1; 902 } 903 jas_image_writecmptsample(image, newcmptno, i, j, 904 lutents[v]); 905 } 906 } 907 return 0; 908} 909 910int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y) 911{ 912 jas_image_cmpt_t *cmpt; 913 uint_fast32_t v; 914 int k; 915 int c; 916 917 cmpt = image->cmpts_[cmptno]; 918 919 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, 920 SEEK_SET) < 0) { 921 return -1; 922 } 923 v = 0; 924 for (k = cmpt->cps_; k > 0; --k) { 925 if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { 926 return -1; 927 } 928 v = (v << 8) | (c & 0xff); 929 } 930 return bitstoint(v, cmpt->prec_, cmpt->sgnd_); 931} 932 933void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y, 934 int_fast32_t v) 935{ 936 jas_image_cmpt_t *cmpt; 937 uint_fast32_t t; 938 int k; 939 int c; 940 941 cmpt = image->cmpts_[cmptno]; 942 943 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, 944 SEEK_SET) < 0) { 945 return; 946 } 947 t = inttobits(v, cmpt->prec_, cmpt->sgnd_); 948 for (k = cmpt->cps_; k > 0; --k) { 949 c = (t >> (8 * (cmpt->cps_ - 1))) & 0xff; 950 if (jas_stream_putc(cmpt->stream_, (unsigned char) c) == EOF) { 951 return; 952 } 953 t <<= 8; 954 } 955} 956 957int jas_image_getcmptbytype(jas_image_t *image, int ctype) 958{ 959 int cmptno; 960 961 for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { 962 if (image->cmpts_[cmptno]->type_ == ctype) { 963 return cmptno; 964 } 965 } 966} 967