예제 #1
0
파일: jpc_mqenc.c 프로젝트: ImageMagick/jp2
jpc_mqenc_t *jpc_mqenc_create(int maxctxs, jas_stream_t *out)
{
	jpc_mqenc_t *mqenc;

	/* Allocate memory for the MQ encoder. */
	if (!(mqenc = jas_malloc(sizeof(jpc_mqenc_t)))) {
		goto error;
	}
	mqenc->out = out;
	mqenc->maxctxs = maxctxs;

	/* Allocate memory for the per-context state information. */
	if (!(mqenc->ctxs = jas_alloc2(mqenc->maxctxs, sizeof(jpc_mqstate_t *)))) {
		goto error;
	}

	/* Set the current context to the first one. */
	mqenc->curctx = mqenc->ctxs;

	jpc_mqenc_init(mqenc);

	/* Initialize the per-context state information to something sane. */
	jpc_mqenc_setctxs(mqenc, 0, 0);

	return mqenc;

error:
	if (mqenc) {
		jpc_mqenc_destroy(mqenc);
	}
	return 0;
}
예제 #2
0
void *jas_calloc(size_t nmemb, size_t size)
{
	void *ptr;

	ptr = jas_alloc2(nmemb, size);
	if (ptr)
		memset(ptr, 0, nmemb*size);
	return ptr;
}
예제 #3
0
void *jas_alloc3(size_t a, size_t b, size_t c)
{
	size_t n;

	if (a && SIZE_MAX / a < b) {
		errno = ENOMEM;
		return NULL;
	}

	return jas_alloc2(a*b, c);
}
예제 #4
0
void *jas_realloc2(void *ptr, size_t nmemb, size_t size)
{
	if (!ptr)
		return jas_alloc2(nmemb, size);
	if (nmemb && SIZE_MAX / nmemb < size) {
		errno = ENOMEM;
		return NULL;
	}
	return jas_realloc(ptr, nmemb * size);

}
예제 #5
0
파일: jpc_util.c 프로젝트: 007Indian/opencv
int jpc_atoaf(char *s, int *numvalues, double **values)
{
    static char delim[] = ", \t\n";
    char buf[4096];
    int n;
    double *vs;
    char *cp;

    strncpy(buf, s, sizeof(buf));
    buf[sizeof(buf) - 1] = '\0';
    n = 0;
    if ((cp = strtok(buf, delim))) {
        ++n;
        while ((cp = strtok(0, delim))) {
            if (cp != '\0') {
                ++n;
            }
        }
    }

    if (n) {
        if (!(vs = jas_alloc2(n, sizeof(double)))) {
            return -1;
        }

        strncpy(buf, s, sizeof(buf));
        buf[sizeof(buf) - 1] = '\0';
        n = 0;
        if ((cp = strtok(buf, delim))) {
            vs[n] = atof(cp);
            ++n;
            while ((cp = strtok(0, delim))) {
                if (cp != '\0') {
                    vs[n] = atof(cp);
                    ++n;
                }
            }
        }
    } else {
        vs = 0;
    }

    *numvalues = n;
    *values = vs;

    return 0;
}
예제 #6
0
파일: jpc_cs.c 프로젝트: Distrotech/jasper
static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
  jas_stream_t *in)
{
	jpc_siz_t *siz = &ms->parms.siz;
	unsigned int i;
	uint_fast8_t tmp;

	/* Eliminate compiler warning about unused variables. */
	cstate = 0;

	if (jpc_getuint16(in, &siz->caps) ||
	  jpc_getuint32(in, &siz->width) ||
	  jpc_getuint32(in, &siz->height) ||
	  jpc_getuint32(in, &siz->xoff) ||
	  jpc_getuint32(in, &siz->yoff) ||
	  jpc_getuint32(in, &siz->tilewidth) ||
	  jpc_getuint32(in, &siz->tileheight) ||
	  jpc_getuint32(in, &siz->tilexoff) ||
	  jpc_getuint32(in, &siz->tileyoff) ||
	  jpc_getuint16(in, &siz->numcomps)) {
		return -1;
	}
	if (!siz->width || !siz->height || !siz->tilewidth ||
	  !siz->tileheight || !siz->numcomps) {
		return -1;
	}
	if (!(siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t)))) {
		return -1;
	}
	for (i = 0; i < siz->numcomps; ++i) {
		if (jpc_getuint8(in, &tmp) ||
		  jpc_getuint8(in, &siz->comps[i].hsamp) ||
		  jpc_getuint8(in, &siz->comps[i].vsamp)) {
			jas_free(siz->comps);
			return -1;
		}
		siz->comps[i].sgnd = (tmp >> 7) & 1;
		siz->comps[i].prec = (tmp & 0x7f) + 1;
	}
	if (jas_stream_eof(in)) {
		jas_free(siz->comps);
		return -1;
	}
	return 0;
}
예제 #7
0
/* Create a MQ decoder. */
jpc_mqdec_t *jpc_mqdec_create(int maxctxs, jas_stream_t *in)
{
	jpc_mqdec_t *mqdec;

	/* There must be at least one context. */
	assert(maxctxs > 0);

	/* Allocate memory for the MQ decoder. */
	if (!(mqdec = jas_malloc(sizeof(jpc_mqdec_t)))) {
		goto error;
	}
	mqdec->in = in;
	mqdec->maxctxs = maxctxs;
	/* Allocate memory for the per-context state information. */
	if (!(mqdec->ctxs = jas_alloc2(mqdec->maxctxs, sizeof(jpc_mqstate_t *)))) {
		goto error;
	}
	/* Set the current context to the first context. */
	mqdec->curctx = mqdec->ctxs;

	/* If an input stream has been associated with the MQ decoder,
	  initialize the decoder state from the stream. */
	if (mqdec->in) {
		jpc_mqdec_init(mqdec);
	}
	/* Initialize the per-context state information. */
	jpc_mqdec_setctxs(mqdec, 0, 0);

	return mqdec;

error:
	/* Oops...  Something has gone wrong. */
	if (mqdec) {
		jpc_mqdec_destroy(mqdec);
	}
	return 0;
}
예제 #8
0
jpc_tagtree_t *jpc_tagtree_create(int numleafsh, int numleafsv)
{
	int nplh[JPC_TAGTREE_MAXDEPTH];
	int nplv[JPC_TAGTREE_MAXDEPTH];
	jpc_tagtreenode_t *node;
	jpc_tagtreenode_t *parentnode;
	jpc_tagtreenode_t *parentnode0;
	jpc_tagtree_t *tree;
	int i;
	int j;
	int k;
	int numlvls;
	int n;

	assert(numleafsh > 0 && numleafsv > 0);

	if (!(tree = jpc_tagtree_alloc())) {
		return 0;
	}
	tree->numleafsh_ = numleafsh;
	tree->numleafsv_ = numleafsv;

	numlvls = 0;
	nplh[0] = numleafsh;
	nplv[0] = numleafsv;
	do {
		n = nplh[numlvls] * nplv[numlvls];
		nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
		nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
		tree->numnodes_ += n;
		++numlvls;
	} while (n > 1);

	if (!(tree->nodes_ = jas_alloc2(tree->numnodes_, sizeof(jpc_tagtreenode_t)))) {
		return 0;
	}

	/* Initialize the parent links for all nodes in the tree. */

	node = tree->nodes_;
	parentnode = &tree->nodes_[tree->numleafsh_ * tree->numleafsv_];
	parentnode0 = parentnode;

	for (i = 0; i < numlvls - 1; ++i) {
		for (j = 0; j < nplv[i]; ++j) {
			k = nplh[i];
			while (--k >= 0) {
				node->parent_ = parentnode;
				++node;
				if (--k >= 0) {
					node->parent_ = parentnode;
					++node;
				}
				++parentnode;
			}
			if ((j & 1) || j == nplv[i] - 1) {
				parentnode0 = parentnode;
			} else {
				parentnode = parentnode0;
				parentnode0 += nplh[i];
			}
		}
	}
	node->parent_ = 0;

	/* Initialize the data values to something sane. */

	jpc_tagtree_reset(tree);

	return tree;
}
예제 #9
0
/* Encode a single code block. */
int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt, jpc_enc_band_t *band, jpc_enc_cblk_t *cblk)
{
    jpc_enc_pass_t *pass;
    jpc_enc_pass_t *endpasses;
    int bitpos;
    int n;
    int adjust;
    int ret;
    int passtype;
    int t;
    jpc_bitstream_t *bout;
    jpc_enc_pass_t *termpass;
    jpc_enc_rlvl_t *rlvl;
    int vcausal;
    int segsym;
    int termmode;
    int c;

    bout = 0;
    rlvl = band->rlvl;

    cblk->stream = jas_stream_memopen(0, 0);
    assert(cblk->stream);
    cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream);
    assert(cblk->mqenc);
    jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);

    cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0;
    if (cblk->numpasses > 0) {
        cblk->passes = jas_alloc2(cblk->numpasses, sizeof(jpc_enc_pass_t));
        assert(cblk->passes);
    } else {
        cblk->passes = 0;
    }
    endpasses = &cblk->passes[cblk->numpasses];
    for (pass = cblk->passes; pass != endpasses; ++pass) {
        pass->start = 0;
        pass->end = 0;
        pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0);
        pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0);
        pass->lyrno = -1;
if (pass == endpasses - 1) {
assert(pass->term == 1);
    pass->term = 1;
}
    }

    cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2,
      jas_matrix_numcols(cblk->data) + 2);
    assert(cblk->flags);


    bitpos = cblk->numbps - 1;
    pass = cblk->passes;
    n = cblk->numpasses;
    while (--n >= 0) {

        if (pass->type == JPC_SEG_MQ) {
            /* NOP */
        } else {
            assert(pass->type == JPC_SEG_RAW);
            if (!bout) {
                bout = jpc_bitstream_sopen(cblk->stream, "w");
                assert(bout);
            }
        }

#if 1
        passtype = (pass - cblk->passes + 2) % 3;
#else
        passtype = JPC_PASSTYPE(pass - cblk->passes + 2);
#endif
        pass->start = jas_stream_tell(cblk->stream);
#if 0
assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
#endif
        assert(bitpos >= 0);
        vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0;
        segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0;
        if (pass->term) {
            termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ?
              JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1;
        } else {
            termmode = 0;
        }
        switch (passtype) {
        case JPC_SIGPASS:
            ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc,
              bitpos, band->orient, vcausal, cblk->flags,
              cblk->data, termmode, &pass->nmsedec) :
              jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags,
              cblk->data, termmode, &pass->nmsedec);
            break;
        case JPC_REFPASS:
            ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc,
              bitpos, vcausal, cblk->flags, cblk->data, termmode,
              &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos,
              vcausal, cblk->flags, cblk->data, termmode,
              &pass->nmsedec);
            break;
        case JPC_CLNPASS:
            assert(pass->type == JPC_SEG_MQ);
            ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient,
              vcausal, segsym, cblk->flags, cblk->data, termmode,
              &pass->nmsedec);
            break;
        default:
            assert(0);
            break;
        }

        if (pass->type == JPC_SEG_MQ) {
            if (pass->term) {
                jpc_mqenc_init(cblk->mqenc);
            }
            jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate);
            pass->end = jas_stream_tell(cblk->stream);
            if (tcmpt->cblksty & JPC_COX_RESET) {
                jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
            }
        } else {
            if (pass->term) {
                if (jpc_bitstream_pending(bout)) {
                    jpc_bitstream_outalign(bout, 0x2a);
                }
                jpc_bitstream_close(bout);
                bout = 0;
                pass->end = jas_stream_tell(cblk->stream);
            } else {
                pass->end = jas_stream_tell(cblk->stream) +
                  jpc_bitstream_pending(bout);
/* NOTE - This will not work.  need to adjust by # of pending output bytes */
            }
        }
#if 0
/* XXX - This assertion fails sometimes when various coding modes are used.
This seems to be harmless, but why does it happen at all? */
assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
#endif

        pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
          jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
          jpc_fixtodbl(band->synweight) *
          jpc_fixtodbl(band->synweight) *
          jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) *
          ((double) (1 << bitpos)) * ((double)(1 << bitpos)) *
          jpc_fixtodbl(pass->nmsedec);
        pass->cumwmsedec = pass->wmsedec;
        if (pass != cblk->passes) {
            pass->cumwmsedec += pass[-1].cumwmsedec;
        }
        if (passtype == JPC_CLNPASS) {
            --bitpos;
        }
        ++pass;
    }

#if 0
dump_passes(cblk->passes, cblk->numpasses, cblk);
#endif

    n = 0;
    endpasses = &cblk->passes[cblk->numpasses];
    for (pass = cblk->passes; pass != endpasses; ++pass) {
        if (pass->start < n) {
            pass->start = n;
        }
        if (pass->end < n) {
            pass->end = n;
        }
        if (!pass->term) {
            termpass = pass;
            while (termpass - pass < cblk->numpasses &&
              !termpass->term) {
                ++termpass;
            }
            if (pass->type == JPC_SEG_MQ) {
                t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0;
                if (pass->mqencstate.ctreg >= 5) {
                    adjust = 4 + t;
                } else {
                    adjust = 5 + t;
                }
                pass->end += adjust;
            }
            if (pass->end > termpass->end) {
                pass->end = termpass->end;
            }
            if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) {
                abort();
            }
            if (c == 0xff) {
                ++pass->end;
            }
            n = JAS_MAX(n, pass->end);
        } else {
            n = JAS_MAX(n, pass->end);
        }
    }

#if 0
dump_passes(cblk->passes, cblk->numpasses, cblk);
#endif

    if (bout) {
        jpc_bitstream_close(bout);
    }

    return 0;
}
예제 #10
0
jpc_pi_t *jpc_enc_pi_create(jpc_enc_cp_t *cp, jpc_enc_tile_t *tile)
{
	jpc_pi_t *pi;
	int compno;
	jpc_picomp_t *picomp;
	jpc_pirlvl_t *pirlvl;
	jpc_enc_tcmpt_t *tcomp;
	int rlvlno;
	jpc_enc_rlvl_t *rlvl;
	int prcno;
	int *prclyrno;

	if (!(pi = jpc_pi_create0())) {
		return 0;
	}
	pi->pktno = -1;
	pi->numcomps = cp->numcmpts;
	if (!(pi->picomps = jas_alloc2(pi->numcomps, sizeof(jpc_picomp_t)))) {
		jpc_pi_destroy(pi);
		return 0;
	}
	for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; ++compno,
	  ++picomp) {
		picomp->pirlvls = 0;
	}

	for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps;
	  compno < pi->numcomps; ++compno, ++tcomp, ++picomp) {
		picomp->numrlvls = tcomp->numrlvls;
		if (!(picomp->pirlvls = jas_alloc2(picomp->numrlvls,
		  sizeof(jpc_pirlvl_t)))) {
			jpc_pi_destroy(pi);
			return 0;
		}
		for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno <
		  picomp->numrlvls; ++rlvlno, ++pirlvl) {
			pirlvl->prclyrnos = 0;
		}
		for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls;
		  rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) {
/* XXX sizeof(long) should be sizeof different type */
			pirlvl->numprcs = rlvl->numprcs;
			if (rlvl->numprcs) {
				if (!(pirlvl->prclyrnos = jas_alloc2(pirlvl->numprcs,
				  sizeof(long)))) {
					jpc_pi_destroy(pi);
					return 0;
				}
			} else {
				pirlvl->prclyrnos = 0;
			}
		}
	}

	pi->maxrlvls = 0;
	for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps;
	  compno < pi->numcomps; ++compno, ++tcomp, ++picomp) {
		picomp->hsamp = cp->ccps[compno].sampgrdstepx;
		picomp->vsamp = cp->ccps[compno].sampgrdstepy;
		for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls;
		  rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) {
			pirlvl->prcwidthexpn = rlvl->prcwidthexpn;
			pirlvl->prcheightexpn = rlvl->prcheightexpn;
			for (prcno = 0, prclyrno = pirlvl->prclyrnos;
			  prcno < pirlvl->numprcs; ++prcno, ++prclyrno) {
				*prclyrno = 0;
			}
			pirlvl->numhprcs = rlvl->numhprcs;
		}
		if (pi->maxrlvls < tcomp->numrlvls) {
			pi->maxrlvls = tcomp->numrlvls;
		}
	}

	pi->numlyrs = tile->numlyrs;
	pi->xstart = tile->tlx;
	pi->ystart = tile->tly;
	pi->xend = tile->brx;
	pi->yend = tile->bry;

	pi->picomp = 0;
	pi->pirlvl = 0;
	pi->x = 0;
	pi->y = 0;
	pi->compno = 0;
	pi->rlvlno = 0;
	pi->prcno = 0;
	pi->lyrno = 0;
	pi->xstep = 0;
	pi->ystep = 0;

	pi->pchgno = -1;

	pi->defaultpchg.prgord = tile->prg;
	pi->defaultpchg.compnostart = 0;
	pi->defaultpchg.compnoend = pi->numcomps;
	pi->defaultpchg.rlvlnostart = 0;
	pi->defaultpchg.rlvlnoend = pi->maxrlvls;
	pi->defaultpchg.lyrnoend = pi->numlyrs;
	pi->pchg = 0;

	pi->valid = 0;

	return pi;
}
예제 #11
0
int jp2_encode(jas_image_t *image, jas_stream_t *out, const char *optstr)
{
	jp2_box_t *box;
	jp2_ftyp_t *ftyp;
	jp2_ihdr_t *ihdr;
	jas_stream_t *tmpstream;
	int allcmptssame;
	jp2_bpcc_t *bpcc;
	long len;
	uint_fast16_t cmptno;
	jp2_colr_t *colr;
	char buf[4096];
	uint_fast32_t overhead;
	jp2_cdefchan_t *cdefchanent;
	jp2_cdef_t *cdef;
	int i;
	uint_fast32_t typeasoc;
	jas_iccprof_t *iccprof;
	jas_stream_t *iccstream;
	int pos;
	int needcdef;
	int prec;
	int sgnd;

	box = 0;
	tmpstream = 0;

	allcmptssame = 1;
	sgnd = jas_image_cmptsgnd(image, 0);
	prec = jas_image_cmptprec(image, 0);
	for (i = 1; i < jas_image_numcmpts(image); ++i) {
		if (jas_image_cmptsgnd(image, i) != sgnd ||
		  jas_image_cmptprec(image, i) != prec) {
			allcmptssame = 0;
			break;
		}
	}

	/* Output the signature box. */

	if (!(box = jp2_box_create(JP2_BOX_JP))) {
		goto error;
	}
	box->data.jp.magic = JP2_JP_MAGIC;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Output the file type box. */

	if (!(box = jp2_box_create(JP2_BOX_FTYP))) {
		goto error;
	}
	ftyp = &box->data.ftyp;
	ftyp->majver = JP2_FTYP_MAJVER;
	ftyp->minver = JP2_FTYP_MINVER;
	ftyp->numcompatcodes = 1;
	ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/*
	 * Generate the data portion of the JP2 header box.
	 * We cannot simply output the header for this box
	 * since we do not yet know the correct value for the length
	 * field.
	 */

	if (!(tmpstream = jas_stream_memopen(0, 0))) {
		goto error;
	}

	/* Generate image header box. */

	if (!(box = jp2_box_create(JP2_BOX_IHDR))) {
		goto error;
	}
	ihdr = &box->data.ihdr;
	ihdr->width = jas_image_width(image);
	ihdr->height = jas_image_height(image);
	ihdr->numcmpts = jas_image_numcmpts(image);
	ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0),
	  jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL;
	ihdr->comptype = JP2_IHDR_COMPTYPE;
	ihdr->csunk = 0;
	ihdr->ipr = 0;
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Generate bits per component box. */

	if (!allcmptssame) {
		if (!(box = jp2_box_create(JP2_BOX_BPCC))) {
			goto error;
		}
		bpcc = &box->data.bpcc;
		bpcc->numcmpts = jas_image_numcmpts(image);
		if (!(bpcc->bpcs = jas_alloc2(bpcc->numcmpts,
		  sizeof(uint_fast8_t)))) {
			goto error;
		}
		for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) {
			bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image,
			  cmptno), jas_image_cmptprec(image, cmptno));
		}
		if (jp2_box_put(box, tmpstream)) {
			goto error;
		}
		jp2_box_destroy(box);
		box = 0;
	}

	/* Generate color specification box. */

	if (!(box = jp2_box_create(JP2_BOX_COLR))) {
		goto error;
	}
	colr = &box->data.colr;
	switch (jas_image_clrspc(image)) {
	case JAS_CLRSPC_SRGB:
	case JAS_CLRSPC_SYCBCR:
	case JAS_CLRSPC_SGRAY:
		colr->method = JP2_COLR_ENUM;
		colr->csid = clrspctojp2(jas_image_clrspc(image));
		colr->pri = JP2_COLR_PRI;
		colr->approx = 0;
		break;
	default:
		colr->method = JP2_COLR_ICC;
		colr->pri = JP2_COLR_PRI;
		colr->approx = 0;
		iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image));
		assert(iccprof);
		iccstream = jas_stream_memopen(0, 0);
		assert(iccstream);
		if (jas_iccprof_save(iccprof, iccstream))
			abort();
		if ((pos = jas_stream_tell(iccstream)) < 0)
			abort();
		colr->iccplen = pos;
		colr->iccp = jas_malloc(pos);
		assert(colr->iccp);
		jas_stream_rewind(iccstream);
		if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen)
			abort();
		jas_stream_close(iccstream);
		jas_iccprof_destroy(iccprof);
		break;
	}
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	needcdef = 1;
	switch (jas_clrspc_fam(jas_image_clrspc(image))) {
	case JAS_CLRSPC_FAM_RGB:
		if (jas_image_cmpttype(image, 0) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) &&
		  jas_image_cmpttype(image, 1) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) &&
		  jas_image_cmpttype(image, 2) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))
			needcdef = 0;
		break;
	case JAS_CLRSPC_FAM_YCBCR:
		if (jas_image_cmpttype(image, 0) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) &&
		  jas_image_cmpttype(image, 1) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) &&
		  jas_image_cmpttype(image, 2) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))
			needcdef = 0;
		break;
	case JAS_CLRSPC_FAM_GRAY:
		if (jas_image_cmpttype(image, 0) ==
		  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))
			needcdef = 0;
		break;
	default:
		abort();
		break;
	}

	if (needcdef) {
		if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
			goto error;
		}
		cdef = &box->data.cdef;
		cdef->numchans = jas_image_numcmpts(image);
		cdef->ents = jas_alloc2(cdef->numchans, sizeof(jp2_cdefchan_t));
		for (i = 0; i < jas_image_numcmpts(image); ++i) {
			cdefchanent = &cdef->ents[i];
			cdefchanent->channo = i;
			typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i));
			cdefchanent->type = typeasoc >> 16;
			cdefchanent->assoc = typeasoc & 0x7fff;
		}
		if (jp2_box_put(box, tmpstream)) {
			goto error;
		}
		jp2_box_destroy(box);
		box = 0;
	}

	/* Determine the total length of the JP2 header box. */

	len = jas_stream_tell(tmpstream);
	jas_stream_rewind(tmpstream);

	/*
	 * Output the JP2 header box and all of the boxes which it contains.
	 */

	if (!(box = jp2_box_create(JP2_BOX_JP2H))) {
		goto error;
	}
	box->len = len + JP2_BOX_HDRLEN(false);
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	if (jas_stream_copy(out, tmpstream, len)) {
		goto error;
	}

	jas_stream_close(tmpstream);
	tmpstream = 0;

	/*
	 * Output the contiguous code stream box.
	 */

	if (!(box = jp2_box_create(JP2_BOX_JP2C))) {
		goto error;
	}
	box->len = 0;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Output the JPEG-2000 code stream. */

	overhead = jas_stream_getrwcount(out);
	sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""),
	  (unsigned long) overhead);

	if (jpc_encode(image, out, buf)) {
		goto error;
	}

	return 0;

error:

	if (box) {
		jp2_box_destroy(box);
	}
	if (tmpstream) {
		jas_stream_close(tmpstream);
	}
	return -1;
}
예제 #12
0
파일: jp2_dec.c 프로젝트: ImageMagick/jp2
jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr)
{
	jp2_box_t *box;
	int found;
	jas_image_t *image;
	jp2_dec_t *dec;
	bool samedtype;
	int dtype;
	unsigned int i;
	jp2_cmap_t *cmapd;
	jp2_pclr_t *pclrd;
	jp2_cdef_t *cdefd;
	unsigned int channo;
	int newcmptno;
	int_fast32_t *lutents;
#if 0
	jp2_cdefchan_t *cdefent;
	int cmptno;
#endif
	jp2_cmapent_t *cmapent;
	jas_icchdr_t icchdr;
	jas_iccprof_t *iccprof;

	dec = 0;
	box = 0;
	image = 0;

	JAS_DBGLOG(100, ("jp2_decode(%p, \"%s\")\n", in, optstr));

	if (!(dec = jp2_dec_create())) {
		goto error;
	}

	/* Get the first box.  This should be a JP box. */
	if (!(box = jp2_box_get(in))) {
		jas_eprintf("error: cannot get box\n");
		goto error;
	}
	if (box->type != JP2_BOX_JP) {
		jas_eprintf("error: expecting signature box\n");
		goto error;
	}
	if (box->data.jp.magic != JP2_JP_MAGIC) {
		jas_eprintf("incorrect magic number\n");
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Get the second box.  This should be a FTYP box. */
	if (!(box = jp2_box_get(in))) {
		goto error;
	}
	if (box->type != JP2_BOX_FTYP) {
		jas_eprintf("expecting file type box\n");
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Get more boxes... */
	found = 0;
	while ((box = jp2_box_get(in))) {
		if (jas_getdbglevel() >= 1) {
			jas_eprintf("got box type %s\n", box->info->name);
		}
		switch (box->type) {
		case JP2_BOX_JP2C:
			found = 1;
			break;
		case JP2_BOX_IHDR:
			if (!dec->ihdr) {
				dec->ihdr = box;
				box = 0;
			}
			break;
		case JP2_BOX_BPCC:
			if (!dec->bpcc) {
				dec->bpcc = box;
				box = 0;
			}
			break;
		case JP2_BOX_CDEF:
			if (!dec->cdef) {
				dec->cdef = box;
				box = 0;
			}
			break;
		case JP2_BOX_PCLR:
			if (!dec->pclr) {
				dec->pclr = box;
				box = 0;
			}
			break;
		case JP2_BOX_CMAP:
			if (!dec->cmap) {
				dec->cmap = box;
				box = 0;
			}
			break;
		case JP2_BOX_COLR:
			if (!dec->colr) {
				dec->colr = box;
				box = 0;
			}
			break;
		}
		if (box) {
			jp2_box_destroy(box);
			box = 0;
		}
		if (found) {
			break;
		}
	}

	if (!found) {
		jas_eprintf("error: no code stream found\n");
		goto error;
	}

	if (!(dec->image = jpc_decode(in, optstr))) {
		jas_eprintf("error: cannot decode code stream\n");
		goto error;
	}

	/* An IHDR box must be present. */
	if (!dec->ihdr) {
		jas_eprintf("error: missing IHDR box\n");
		goto error;
	}

	/* Does the number of components indicated in the IHDR box match
	  the value specified in the code stream? */
	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint,
	  jas_image_numcmpts(dec->image))) {
		jas_eprintf("warning: number of components mismatch\n");
	}

	/* At least one component must be present. */
	if (!jas_image_numcmpts(dec->image)) {
		jas_eprintf("error: no components\n");
		goto error;
	}

	/* Determine if all components have the same data type. */
	samedtype = true;
	dtype = jas_image_cmptdtype(dec->image, 0);
	for (i = 1; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
		if (jas_image_cmptdtype(dec->image, i) != dtype) {
			samedtype = false;
			break;
		}
	}

	/* Is the component data type indicated in the IHDR box consistent
	  with the data in the code stream? */
	if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) ||
	  (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) {
		jas_eprintf("warning: component data type mismatch\n");
	}

	/* Is the compression type supported? */
	if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) {
		jas_eprintf("error: unsupported compression type\n");
		goto error;
	}

	if (dec->bpcc) {
		/* Is the number of components indicated in the BPCC box
		  consistent with the code stream data? */
		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(jas_uint, jas_image_numcmpts(
		  dec->image))) {
			jas_eprintf("warning: number of components mismatch\n");
		}
		/* Is the component data type information indicated in the BPCC
		  box consistent with the code stream data? */
		if (!samedtype) {
			for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
			  ++i) {
				if (jas_image_cmptdtype(dec->image, i) !=
				  JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) {
					jas_eprintf("warning: component data type mismatch\n");
				}
			}
		} else {
			jas_eprintf("warning: superfluous BPCC box\n");
		}
	}

	/* A COLR box must be present. */
	if (!dec->colr) {
		jas_eprintf("error: no COLR box\n");
		goto error;
	}

	switch (dec->colr->data.colr.method) {
	case JP2_COLR_ENUM:
		jas_image_setclrspc(dec->image, jp2_getcs(&dec->colr->data.colr));
		break;
	case JP2_COLR_ICC:
		iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp,
		  dec->colr->data.colr.iccplen);
		if (!iccprof) {
			jas_eprintf("error: failed to parse ICC profile\n");
			goto error;
		}
		jas_iccprof_gethdr(iccprof, &icchdr);
		jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc);
		jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc));
		dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof);
		assert(dec->image->cmprof_);
		jas_iccprof_destroy(iccprof);
		break;
	}

	/* If a CMAP box is present, a PCLR box must also be present. */
	if (dec->cmap && !dec->pclr) {
		jas_eprintf("warning: missing PCLR box or superfluous CMAP box\n");
		jp2_box_destroy(dec->cmap);
		dec->cmap = 0;
	}

	/* If a CMAP box is not present, a PCLR box must not be present. */
	if (!dec->cmap && dec->pclr) {
		jas_eprintf("warning: missing CMAP box or superfluous PCLR box\n");
		jp2_box_destroy(dec->pclr);
		dec->pclr = 0;
	}

	/* Determine the number of channels (which is essentially the number
	  of components after any palette mappings have been applied). */
	dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans :
	  JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));

	/* Perform a basic sanity check on the CMAP box if present. */
	if (dec->cmap) {
		for (i = 0; i < dec->numchans; ++i) {
			/* Is the component number reasonable? */
			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint,
			  jas_image_numcmpts(dec->image))) {
				jas_eprintf("error: invalid component number in CMAP box\n");
				goto error;
			}
			/* Is the LUT index reasonable? */
			if (dec->cmap->data.cmap.ents[i].pcol >=
			  dec->pclr->data.pclr.numchans) {
				jas_eprintf("error: invalid CMAP LUT index\n");
				goto error;
			}
		}
	}

	/* Allocate space for the channel-number to component-number LUT. */
	if (!(dec->chantocmptlut = jas_alloc2(dec->numchans,
	  sizeof(uint_fast16_t)))) {
		jas_eprintf("error: no memory\n");
		goto error;
	}

	if (!dec->cmap) {
		for (i = 0; i < dec->numchans; ++i) {
			dec->chantocmptlut[i] = i;
		}
	} else {
		cmapd = &dec->cmap->data.cmap;
		pclrd = &dec->pclr->data.pclr;
		cdefd = &dec->cdef->data.cdef;
		for (channo = 0; channo < cmapd->numchans; ++channo) {
			cmapent = &cmapd->ents[channo];
			if (cmapent->map == JP2_CMAP_DIRECT) {
				dec->chantocmptlut[channo] = channo;
			} else if (cmapent->map == JP2_CMAP_PALETTE) {
				lutents = jas_alloc2(pclrd->numlutents, sizeof(int_fast32_t));
				for (i = 0; i < pclrd->numlutents; ++i) {
					lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans];
				}
				newcmptno = jas_image_numcmpts(dec->image);
				jas_image_depalettize(dec->image, cmapent->cmptno,
				  pclrd->numlutents, lutents,
				  JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno);
				dec->chantocmptlut[channo] = newcmptno;
				jas_free(lutents);
#if 0
				if (dec->cdef) {
					cdefent = jp2_cdef_lookup(cdefd, channo);
					if (!cdefent) {
						abort();
					}
				jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), cdefent->type, cdefent->assoc));
				} else {
				jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1));
				}
#endif
			}
		}
	}

	/* Mark all components as being of unknown type. */

	for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
		jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN);
	}

	/* Determine the type of each component. */
	if (dec->cdef) {
		for (i = 0; i < dec->numchans; ++i) {
			/* Is the channel number reasonable? */
			if (dec->cdef->data.cdef.ents[i].channo >= dec->numchans) {
				jas_eprintf("error: invalid channel number in CDEF box\n");
				goto error;
			}
			jas_image_setcmpttype(dec->image,
			  dec->chantocmptlut[dec->cdef->data.cdef.ents[i].channo],
			  jp2_getct(jas_image_clrspc(dec->image),
			  dec->cdef->data.cdef.ents[i].type,
			  dec->cdef->data.cdef.ents[i].assoc));
		}
	} else {
		for (i = 0; i < dec->numchans; ++i) {
			jas_image_setcmpttype(dec->image, dec->chantocmptlut[i],
			  jp2_getct(jas_image_clrspc(dec->image), 0, i + 1));
		}
	}

	/* Delete any components that are not of interest. */
	for (i = jas_image_numcmpts(dec->image); i > 0; --i) {
		if (jas_image_cmpttype(dec->image, i - 1) == JAS_IMAGE_CT_UNKNOWN) {
			jas_image_delcmpt(dec->image, i - 1);
		}
	}

	/* Ensure that some components survived. */
	if (!jas_image_numcmpts(dec->image)) {
		jas_eprintf("error: no components\n");
		goto error;
	}
#if 0
jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image));
#endif

	/* Prevent the image from being destroyed later. */
	image = dec->image;
	dec->image = 0;

	jp2_dec_destroy(dec);

	return image;

error:
	if (box) {
		jp2_box_destroy(box);
	}
	if (dec) {
		jp2_dec_destroy(dec);
	}
	return 0;
}