jas_image.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       jas_image.c (38009B)
       ---
            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) 1999-2000 Image Power, Inc.
           13  * Copyright (c) 1999-2000 The University of British Columbia
           14  * Copyright (c) 2001-2003 Michael David Adams
           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 1918 2005-07-24 14:12:08Z baford $
           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->tlx_ = tlx;
          310         cmpt->tly_ = tly;
          311         cmpt->hstep_ = hstep;
          312         cmpt->vstep_ = vstep;
          313         cmpt->width_ = width;
          314         cmpt->height_ = height;
          315         cmpt->prec_ = depth;
          316         cmpt->sgnd_ = sgnd;
          317         cmpt->stream_ = 0;
          318         cmpt->cps_ = (depth + 7) / 8;
          319 
          320         size = cmpt->width_ * cmpt->height_ * cmpt->cps_;
          321 //        cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) : jas_stream_tmpfile();
          322         cmpt->stream_ = jas_stream_memopen(0, size);        // XXX vx32 hack
          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_, (int)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 fprintf(stderr, "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 fprintf(stderr, "INIMAGE\n");
         1438 jas_image_dump(inimage, stderr);
         1439 fprintf(stderr, "OUTIMAGE\n");
         1440 jas_image_dump(outimage, stderr);
         1441 #endif
         1442         return outimage;
         1443 error:
         1444         return 0;
         1445 }