Beispiel #1
0
ICCProfile JP2Instance::ReadICCProfile()
{
   CheckOpenStream( !m_path.IsEmpty() && s_jasperInitialized, "ReadICCProfile" );

   if ( jas_image_cmprof( m_jp2Image ) == nullptr )
      return ICCProfile();

   jas_stream_t* iccStream = nullptr;
   try
   {
      // Create a growable memory stream for output
      iccStream = jas_stream_memopen( 0, 0 );

      if ( iccStream == nullptr )
         JP2KERROR( "Extracting ICC profile from JPEG2000 image: Unable to create JasPer stream" );

      if ( jas_iccprof_save( jas_image_cmprof( m_jp2Image )->iccprof, iccStream ) < 0 )
         JP2KERROR( "Extracting ICC profile from JPEG2000 image: Error saving profile to JasPer stream" );

      long iccSize = jas_stream_tell( iccStream );

      if ( iccSize <= 0 )
         JP2KERROR( "Extracting ICC profile from JPEG2000 image: Invalid JasPer stream position" );

      ByteArray iccData( iccSize );

      jas_stream_rewind( iccStream );

      if ( jas_stream_read( iccStream, iccData.Begin(), iccSize ) != iccSize )
         JP2KERROR( "Extracting ICC profile from JPEG2000 image: Error reading JasPer stream" );

      jas_stream_close( iccStream ), iccStream = nullptr;

      ICCProfile icc( iccData );
      if ( icc.IsProfile() )
         Console().WriteLn( "<end><cbr>ICC profile extracted: \'" + icc.Description() + "\', " + String( icc.ProfileSize() ) + " bytes." );
      return icc;
   }
   catch ( ... )
   {
      if ( iccStream != nullptr )
         jas_stream_close( iccStream );
      Close();
      throw;
   }
}
Beispiel #2
0
int jp2_write_header(jas_image_t *image, jas_stream_t *out)
{
	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;
	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_malloc(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_malloc(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;
	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;

	return 0;
	abort();

error:

	if (box) {
		jp2_box_destroy(box);
	}
	if (tmpstream) {
		jas_stream_close(tmpstream);
	}
	return -1;
}
Beispiel #3
0
static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
  jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
{
	jpc_dec_seg_t *seg;
	int i;
	int bpno;
	int passtype;
	int ret;
	int compno;
	int filldata;
	int fillmask;
	jpc_dec_ccp_t *ccp;

	compno = tcomp - tile->tcomps;

	if (!cblk->flags) {
		/* Note: matrix is assumed to be zeroed */
		if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
		  2, jas_matrix_numcols(cblk->data) + 2))) {
			return -1;
		}
	}

	seg = cblk->segs.head;
	while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
	  seg->lyrno < maxlyrs)) {
		assert(seg->numpasses >= seg->maxpasses || dopartial);
		assert(seg->stream);
		jas_stream_rewind(seg->stream);
		jas_stream_setrwcount(seg->stream, 0);
		if (seg->type == JPC_SEG_MQ) {
			if (!cblk->mqdec) {
				if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
					return -1;
				}
				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
			}
			jpc_mqdec_setinput(cblk->mqdec, seg->stream);
			jpc_mqdec_init(cblk->mqdec);
		} else {
			assert(seg->type == JPC_SEG_RAW);
			if (!cblk->nulldec) {
				if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
					assert(0);
				}
			}
		}


		for (i = 0; i < seg->numpasses; ++i) {
			if (cblk->numimsbs > band->numbps) {
				ccp = &tile->cp->ccps[compno];
				if (ccp->roishift <= 0) {
					jas_eprintf("warning: corrupt code stream\n");
				} else {
					if (cblk->numimsbs < ccp->roishift - band->numbps) {
						jas_eprintf("warning: corrupt code stream\n");
					}
				}
			}
			bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
			  (seg->passno + i - cblk->firstpassno + 2) / 3);
if (bpno < 0) {
	goto premature_exit;
}
#if 1
			passtype = (seg->passno + i + 2) % 3;
#else
			passtype = JPC_PASSTYPE(seg->passno + i + 2);
#endif
			assert(bpno >= 0 && bpno < 31);
			switch (passtype) {
			case JPC_SIGPASS:
				ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
				  cblk->mqdec, bpno, band->orient,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data) :
				  dec_rawsigpass(dec, cblk->nulldec, bpno,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data);
				break;
			case JPC_REFPASS:
				ret = (seg->type == JPC_SEG_MQ) ?
				  dec_refpass(dec, cblk->mqdec, bpno,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data) :
				  dec_rawrefpass(dec, cblk->nulldec, bpno,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data);
				break;
			case JPC_CLNPASS:
				assert(seg->type == JPC_SEG_MQ);
				ret = dec_clnpass(dec, cblk->mqdec, bpno,
				  band->orient, (tile->cp->ccps[compno].cblkctx &
				  JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
				  JPC_COX_SEGSYM) != 0, cblk->flags,
				  cblk->data);
				break;
			default:
				ret = -1;
				break;
			}
			/* Do we need to reset after each coding pass? */
			if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
			}

			if (ret) {
				jas_eprintf("coding pass failed passtype=%d segtype=%d\n", passtype, seg->type);
				return -1;
			}

		}

		if (seg->type == JPC_SEG_MQ) {
/* Note: dont destroy mq decoder because context info will be lost */
		} else {
			assert(seg->type == JPC_SEG_RAW);
			if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
				fillmask = 0x7f;
				filldata = 0x2a;
			} else {
				fillmask = 0;
				filldata = 0;
			}
			if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
			  filldata)) < 0) {
				return -1;
			} else if (ret > 0) {
				jas_eprintf("warning: bad termination pattern detected\n");
			}
			jpc_bitstream_close(cblk->nulldec);
			cblk->nulldec = 0;
		}

		cblk->curseg = seg->next;
		jpc_seglist_remove(&cblk->segs, seg);
		jpc_seg_destroy(seg);
		seg = cblk->curseg;
	}

	assert(dopartial ? (!cblk->curseg) : 1);

premature_exit:
	return 0;
}
static GstFlowReturn
gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf)
{
    GstFlowReturn ret = GST_FLOW_OK;
    jas_stream_t *stream = NULL;
    gint i;
    guint size, boxsize;

    g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);

    *outbuf = NULL;

    boxsize = (enc->mode == GST_JP2ENC_MODE_J2C) ? 8 : 0;

    if (!(stream = jas_stream_memopen (NULL, 0)))
        goto fail_stream;

    for (i = 0; i < enc->channels; ++i) {
        gint x, y, cwidth, cheight, inc, stride, cmpt;
        guint8 *row_pix, *in_pix;
        glong *tb;

        cmpt = i;
        inc = enc->inc[i];
        stride = enc->stride[i];
        cheight = enc->cheight[cmpt];
        cwidth = enc->cwidth[cmpt];

        GST_LOG_OBJECT (enc,
                        "write component %d<=%d, size %dx%d, offset %d, inc %d, stride %d",
                        i, cmpt, cwidth, cheight, enc->offset[i], inc, stride);

        row_pix = data + enc->offset[i];

        for (y = 0; y < cheight; y++) {
            in_pix = row_pix;
            tb = enc->buf;
            for (x = 0; x < cwidth; x++) {
                *tb = *in_pix;
                in_pix += inc;
                tb++;
            }
            if (jas_image_writecmpt2 (enc->image, cmpt, 0, y, cwidth, 1, enc->buf))
                goto fail_image;
            row_pix += stride;
        }
    }

    GST_LOG_OBJECT (enc, "all components written");

    if (jas_image_encode (enc->image, stream, enc->fmt, (char *) "sop"))
        goto fail_encode;

    GST_LOG_OBJECT (enc, "image encoded");

    size = jas_stream_length (stream);
    ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
            GST_BUFFER_OFFSET_NONE, size + boxsize, GST_PAD_CAPS (enc->srcpad),
            outbuf);

    if (ret != GST_FLOW_OK)
        goto no_buffer;

    data = GST_BUFFER_DATA (*outbuf);
    if (jas_stream_flush (stream) ||
            jas_stream_rewind (stream) < 0 ||
            jas_stream_read (stream, data + boxsize, size) < size)
        goto fail_image_out;

    if (boxsize) {
        /* write atom prefix */
        GST_WRITE_UINT32_BE (data, size + 8);
        GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c'));
    }

done:
    if (stream)
        jas_stream_close (stream);

    return ret;

    /* ERRORS */
fail_stream:
    {
        GST_DEBUG_OBJECT (enc, "Failed to create inputstream.");
        goto fail;
    }
fail_encode:
    {
        GST_DEBUG_OBJECT (enc, "Failed to encode image.");
        goto fail;
    }
fail_image:
    {
        GST_DEBUG_OBJECT (enc, "Failed to process input image.");
        goto fail;
    }
fail_image_out:
    {
        GST_DEBUG_OBJECT (enc, "Failed to process encoded image.");
        goto fail;
    }
fail:
    {
        if (*outbuf)
            gst_buffer_unref (*outbuf);
        *outbuf = NULL;
        GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), (NULL));
        ret = GST_FLOW_ERROR;
        goto done;
    }
no_buffer:
    {
        GST_DEBUG_OBJECT (enc, "Failed to create outbuffer - %s",
                          gst_flow_get_name (ret));
        goto done;
    }
}
Beispiel #5
0
void jpc_init_t2state(jpc_enc_t *enc, int raflag)
{
/* It is assumed that band->numbps and cblk->numbps precomputed */

	jpc_enc_tcmpt_t *comp;
	jpc_enc_tcmpt_t *endcomps;
	jpc_enc_rlvl_t *lvl;
	jpc_enc_rlvl_t *endlvls;
	jpc_enc_band_t *band;
	jpc_enc_band_t *endbands;
	jpc_enc_cblk_t *cblk;
	jpc_enc_cblk_t *endcblks;
	jpc_enc_pass_t *pass;
	jpc_enc_pass_t *endpasses;
	jpc_tagtreenode_t *leaf;
	jpc_enc_tile_t *tile;
	int prcno;
	jpc_enc_prc_t *prc;

	tile = enc->curtile;

	endcomps = &tile->tcmpts[tile->numtcmpts];
	for (comp = tile->tcmpts; comp != endcomps; ++comp) {
		endlvls = &comp->rlvls[comp->numrlvls];
		for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
			if (!lvl->bands) {
				continue;
			}
			endbands = &lvl->bands[lvl->numbands];
			for (band = lvl->bands; band != endbands; ++band) {
				if (!band->data) {
					continue;
				}
				for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) {
					if (!prc->cblks) {
						continue;
					}
					jpc_tagtree_reset(prc->incltree);
					jpc_tagtree_reset(prc->nlibtree);
					endcblks = &prc->cblks[prc->numcblks];
					for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
						if (jas_stream_rewind(cblk->stream)) {
							assert(0);
						}
						cblk->curpass = (cblk->numpasses > 0) ? cblk->passes : 0;
						cblk->numencpasses = 0;
						cblk->numlenbits = 3;
						cblk->numimsbs = band->numbps - cblk->numbps;
						assert(cblk->numimsbs >= 0);
						leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks);
						jpc_tagtree_setvalue(prc->nlibtree, leaf, cblk->numimsbs);

						if (raflag) {
							endpasses = &cblk->passes[cblk->numpasses];
							for (pass = cblk->passes; pass != endpasses; ++pass) {
								pass->lyrno = -1;
								pass->lyrno = 0;
							}
						}
					}
				}
			}
		}
	}

}
Beispiel #6
0
int jp2_encode(jas_image_t *image, jas_stream_t *out, 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;

	box = 0;
	tmpstream = 0;

	/* 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);
	allcmptssame = 0;
	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_malloc(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;
	colr->method = JP2_COLR_ENUM;
	colr->pri = JP2_COLR_PRI;
	colr->approx = 0;
	colr->csid = (jas_image_colorspace(image) == JAS_IMAGE_CS_RGB) ? JP2_COLR_SRGB :
	  JP2_COLR_SGRAY;
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	if (!(jas_image_colorspace(image) == JAS_IMAGE_CS_RGB &&
	  jas_image_numcmpts(image) == 3 &&
	  jas_image_getcmptbytype(image, 0) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R) &&
	  jas_image_getcmptbytype(image, 1) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G) &&
	  jas_image_getcmptbytype(image, 2) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B)) &&
	  !(jas_image_colorspace(image) == JAS_IMAGE_CS_YCBCR &&
	  jas_image_numcmpts(image) != 3 &&
	  jas_image_getcmptbytype(image, 0) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_Y) &&
	  jas_image_getcmptbytype(image, 1) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CB) &&
	  jas_image_getcmptbytype(image, 2) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CR)) &&
	  !(jas_image_colorspace(image) == JAS_IMAGE_CS_GRAY &&
	  jas_image_numcmpts(image) == 1 &&
	  jas_image_getcmptbytype(image, 0) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))) {

		if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
			goto error;
		}
		cdef = &box->data.cdef;
		cdef->numchans = jas_image_numcmpts(image);
		cdef->ents = jas_malloc(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_colorspace(image), jas_image_cmpttype(image, i));
			cdefchanent->type = typeasoc >> 16;
			cdefchanent->assoc = typeasoc & 0x7fff;
		}
		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;
	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;
	abort();

error:

	if (box) {
		jp2_box_destroy(box);
	}
	if (tmpstream) {
		jas_stream_close(tmpstream);
	}
	return -1;
}
Beispiel #7
0
int img_dat_generate(IMG_DAT **oimg_dat, jas_image_t *image)
{
   IMG_DAT *img_dat;
   int i;
   int cmptscnt;
   int rwcnt;
   int max_hor, max_vrt;

   /* Allocate memory for image data structure. */
   img_dat = (IMG_DAT *)calloc(1, sizeof(IMG_DAT));
   if(img_dat == NULL){
      fprintf(stderr, "ERROR : img_dat_generate : "
              "calloc : img_dat (%lu bytes)\n", (unsigned long)sizeof(IMG_DAT));
      return(-2);
   }

   /* Get component count. */
   cmptscnt = jas_image_numcmpts(image);

   /* Initialize img_dat info */
   img_dat->max_width = jas_image_brx(image);
   img_dat->max_height = jas_image_bry(image);
   img_dat->ppi = -1;
   img_dat->intrlv = 0;
   img_dat->n_cmpnts = cmptscnt;
   img_dat->cmpnt_depth = jas_image_cmptprec(image, 0);

   max_hor = -1;
   max_vrt = -1;
   img_dat->pix_depth = 0;

   for(i = 0; i < cmptscnt; i++){
      int cdepth;

      img_dat->hor_sampfctr[i] = 1;
      img_dat->vrt_sampfctr[i] = 1;
      cdepth = jas_image_cmptprec(image, i);
      img_dat->pix_depth += cdepth;
      if (cdepth != img_dat->cmpnt_depth) {
         fprintf(stderr, "WARNING : img_dat_generate: "
                 "unequal component depths, 0: %d and %d: %d\n",
                 i, cdepth, jas_image_cmptprec(image, i));
      }

      if(max_hor < img_dat->hor_sampfctr[i])
         max_hor = img_dat->hor_sampfctr[i];
      if(max_vrt < img_dat->vrt_sampfctr[i])
         max_vrt = img_dat->vrt_sampfctr[i];
   }

   for(i = 0; i < img_dat->n_cmpnts; i++){
      img_dat->samp_width[i] = (int)ceil(img_dat->max_width *
                   (img_dat->hor_sampfctr[i]/(double)max_hor));
      img_dat->samp_height[i] = (int)ceil(img_dat->max_height *
                   (img_dat->vrt_sampfctr[i]/(double)max_vrt));
   }

   /* Put the image raw pixels to image data sturcture component plains. */
   cmptscnt = jas_image_numcmpts(image);
   for (i = 0; i < cmptscnt; i++){
      jas_stream_rewind(image->cmpts_[i]->stream_);
      rwcnt = jas_stream_getrwcount(image->cmpts_[i]->stream_) - 1;
      img_dat->image[i]  = (unsigned char *)malloc(rwcnt * sizeof(unsigned char));
      if(img_dat->image[i] == NULL){
         fprintf(stderr, "ERROR : get_raw_image: "
                 "calloc : img_dat->image[%d] (%lu bytes)\n",
                 i, (unsigned long)(rwcnt * sizeof(unsigned char)));
         return(-3);
      }
      jas_stream_read(image->cmpts_[i]->stream_, img_dat->image[i], rwcnt);
   }

   *oimg_dat = img_dat;

   return(0);
}