int jp2_write_codestream(jas_image_t *image, jas_stream_t *out, char *optstr) { jp2_box_t *box; char buf[4096]; uint_fast32_t overhead; /* * 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); } return -1; }
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; 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(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; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }
int enc_jpeg2000(unsigned char *cin,g2int width,g2int height,g2int nbits, g2int ltype, g2int ratio, g2int retry, char *outjpc, g2int jpclen) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: enc_jpeg2000 Encodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function encodes a grayscale image into a JPEG2000 code stream * specified in the JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) * using JasPer Software version 1.500.4 (or 1.700.2 ) written by the * University of British Columbia, Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * 2004-12-16 Gilbert - Added retry argument/option to allow option of * increasing the maximum number of guard bits to the * JPEG2000 algorithm. * * USAGE: int enc_jpeg2000(unsigned char *cin,g2int width,g2int height, * g2int nbits, g2int ltype, g2int ratio, * g2int retry, char *outjpc, g2int jpclen) * * INPUT ARGUMENTS: * cin - Packed matrix of Grayscale image values to encode. * width - width of image * height - height of image * nbits - depth (in bits) of image. i.e number of bits * used to hold each data value * ltype - indicator of lossless or lossy compression * = 1, for lossy compression * != 1, for lossless compression * ratio - target compression ratio. (ratio:1) * Used only when ltype == 1. * retry - Pointer to option type. * 1 = try increasing number of guard bits * otherwise, no additional options * jpclen - Number of bytes allocated for new JPEG2000 code stream in * outjpc. * * INPUT ARGUMENTS: * outjpc - Output encoded JPEG2000 code stream * * RETURN VALUES : * > 0 = Length in bytes of encoded JPEG2000 code stream * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { int ier,rwcnt; jas_image_t image; jas_stream_t *jpcstream,*istream; jas_image_cmpt_t cmpt,*pcmpt; #define MAXOPTSSIZE 1024 char opts[MAXOPTSSIZE]; /* printf(" enc_jpeg2000:width %ld\n",width); printf(" enc_jpeg2000:height %ld\n",height); printf(" enc_jpeg2000:nbits %ld\n",nbits); printf(" enc_jpeg2000:jpclen %ld\n",jpclen); */ // jas_init(); // // Set lossy compression options, if requested. // if ( ltype != 1 ) { opts[0]=(char)0; } else { #ifdef _SAGA_MSW sprintf(opts,"mode=real\nrate=%f",1.0/(float)ratio); #else snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/(float)ratio); #endif // _SAGA_MSW } if ( retry == 1 ) { // option to increase number of guard bits strcat(opts,"\nnumgbits=4"); } //printf("SAGopts: %s\n",opts); // // Initialize the JasPer image structure describing the grayscale // image to encode into the JPEG2000 code stream. // image.tlx_=0; image.tly_=0; #ifdef JAS_1_500_4 image.brx_=(uint_fast32_t)width; image.bry_=(uint_fast32_t)height; #endif #ifdef JAS_1_700_2 image.brx_=(jas_image_coord_t)width; image.bry_=(jas_image_coord_t)height; #endif image.numcmpts_=1; image.maxcmpts_=1; #ifdef JAS_1_500_4 image.colormodel_=JAS_IMAGE_CM_GRAY; /* grayscale Image */ #endif #ifdef JAS_1_700_2 image.clrspc_=JAS_CLRSPC_SGRAY; /* grayscale Image */ image.cmprof_=0; #endif image.inmem_=1; cmpt.tlx_=0; cmpt.tly_=0; cmpt.hstep_=1; cmpt.vstep_=1; #ifdef JAS_1_500_4 cmpt.width_=(uint_fast32_t)width; cmpt.height_=(uint_fast32_t)height; #endif #ifdef JAS_1_700_2 cmpt.width_=(jas_image_coord_t)width; cmpt.height_=(jas_image_coord_t)height; cmpt.type_=JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y); #endif cmpt.prec_=nbits; cmpt.sgnd_=0; cmpt.cps_=(nbits+7)/8; pcmpt=&cmpt; image.cmpts_=&pcmpt; // // Open a JasPer stream containing the input grayscale values // istream=jas_stream_memopen((char *)cin,height*width*cmpt.cps_); cmpt.stream_=istream; // // Open an output stream that will contain the encoded jpeg2000 // code stream. // jpcstream=jas_stream_memopen(outjpc,(int)jpclen); // // Encode image. // ier=jpc_encode(&image,jpcstream,opts); if ( ier != 0 ) { printf(" jpc_encode return = %d \n",ier); return -3; } // // Clean up JasPer work structures. // rwcnt=jpcstream->rwcnt_; ier=jas_stream_close(istream); ier=jas_stream_close(jpcstream); // // Return size of jpeg2000 code stream // return (rwcnt); }
int TO_jpeg2000(unsigned char *cin,int width,int height,int nbits, int ltype, float ratio, int retry, char *outjpc, int jpclen) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: TO_jpeg2000 Encodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function encodes a grayscale image into a JPEG2000 code stream * specified in the JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) * using JasPer Software version 1.700.2 or better written by the * University of British Columbia, Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * 2004-12-16 Gilbert - Added retry argument/option to allow option of * increasing the maximum number of guard bits to the * JPEG2000 algorithm. * 2015-10-26 M.Valin - removed GRIB library connections, light refactoring, * changed function name * * USAGE: int TO_jpeg2000(unsigned char *cin,int width,int height, * int nbits, int ltype, int ratio, * int retry, char *outjpc, int jpclen) * * INPUT ARGUMENTS: * cin - Packed matrix of Grayscale image values to encode. * (byte stream, MSB first, LSB last for each multibyte item) * width - width of image * height - height of image * nbits - depth (in bits) of image. i.e number of bits * used to hold each data value * ltype - indicator of lossless or lossy compression * = 1, for lossy compression * != 1, for lossless compression * ratio - target compression ratio. (ratio:1) * Used only when ltype == 1. * retry - Pointer to option type. * 1 = try increasing number of guard bits * otherwise, no additional options * jpclen - Number of bytes allocated for new JPEG2000 code stream in * outjpc. * * INPUT ARGUMENTS: * outjpc - Output encoded JPEG2000 code stream * * RETURN VALUES : * > 0 = Length in bytes of encoded JPEG2000 code stream * -3 = Error encoding jpeg2000 code stream. * * REMARKS: * * Requires JasPer Software version 1.700.2 or better * * ATTRIBUTES: * LANGUAGE: C * OS: Linux * *$$$*/ { int ier,rwcnt; jas_image_t image; jas_stream_t *jpcstream,*istream; jas_image_cmpt_t cmpt,*pcmpt; #define MAXOPTSSIZE 1024 char opts[MAXOPTSSIZE]; /* printf(" TO_jpeg2000:width %ld\n",width); printf(" TO_jpeg2000:height %ld\n",height); printf(" TO_jpeg2000:nbits %ld\n",nbits); printf(" TO_jpeg2000:jpclen %ld\n",jpclen); */ // jas_init(); // // Set lossy compression options, if requested. // if ( ltype != 1 ) { opts[0]=(char)0; } else { // snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/(float)ratio); snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/ratio); fprintf(stderr,"using lossy compression\n"); } if ( retry == 1 ) { // option to increase number of guard bits strcat(opts,"\nnumgbits=4"); } //printf("SAGopts: %s\n",opts); // // Initialize the JasPer image structure describing the grayscale // image to encode into the JPEG2000 code stream. // image.tlx_=0; image.tly_=0; image.brx_=(jas_image_coord_t)width; image.bry_=(jas_image_coord_t)height; image.numcmpts_=1; image.maxcmpts_=1; image.clrspc_=JAS_CLRSPC_SGRAY; /* grayscale Image */ image.cmprof_=0; image.inmem_=1; cmpt.tlx_=0; cmpt.tly_=0; cmpt.hstep_=1; cmpt.vstep_=1; cmpt.width_=(jas_image_coord_t)width; cmpt.height_=(jas_image_coord_t)height; cmpt.type_=JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y); cmpt.prec_=nbits; cmpt.sgnd_=0; cmpt.cps_=(nbits+7)/8; pcmpt=&cmpt; image.cmpts_=&pcmpt; #if defined(DEBUG) printf(" SAGOUT ENCODE:\n"); printf(" tlx %d \n",image.tlx_); printf(" tly %d \n",image.tly_); printf(" brx %d \n",image.brx_); printf(" bry %d \n",image.bry_); printf(" numcmpts %d \n",image.numcmpts_); printf(" maxcmpts %d \n",image.maxcmpts_); printf(" colorspace %d \n",image.clrspc_); printf(" inmem %d \n",image.inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); printf(" type %d \n",pcmpt->type_); #endif // // Open a JasPer stream containing the input grayscale values // istream=jas_stream_memopen((char *)cin,height*width*cmpt.cps_); cmpt.stream_=istream; // // Open an output stream that will contain the encoded jpeg2000 // code stream. // jpcstream=jas_stream_memopen(outjpc,(int)jpclen); // // Encode image. // ier=jpc_encode(&image,jpcstream,opts); if ( ier != 0 ) { printf(" jpc_encode return = %d \n",ier); return -3; } // // Clean up JasPer work structures. // rwcnt=jpcstream->rwcnt_; ier=jas_stream_close(istream); ier=jas_stream_close(jpcstream); // // Return size of jpeg2000 code stream // return (rwcnt); }