コード例 #1
0
ファイル: decode.c プロジェクト: vitorpy/qwsqviewer
/*************************************************************************
**************************************************************************
#cat:   decode_tagged_field_image() - Takes an ANSI/NIST tagged field
#cat:                image record and decodes its image data (if necessary)
#cat:                and returns the reconstructed pixmap and its attributes.

   Input:
      ansi_nist   - ANSI/NIST file structure
      imgrecord_i - index of record to be decoded
      intrlvflag  - if image data is RGB, then this flagged designates
                    whether the returned pixmap should be interleaved or not
   Output:
      odata  - points to reconstructed pixmap
      ow     - pixel width of pixmap
      oh     - pixel height of pixmap
      od     - pixel depth of pixmap
      oppmm  - scan resolution of pixmap in pixels/mm
   Return Code:
      TRUE     - successful image reconstruction
      FALSE    - image record ignored
      Negative - system error
**************************************************************************/
int decode_tagged_field_image(unsigned char **odata,
                     int *ow, int *oh, int *od, double *oppmm,
                     const ANSI_NIST *ansi_nist, const int imgrecord_i,
                     const int intrlvflag)
{
   int i, ret;
   RECORD *imgrecord;
   FIELD *field;
   int field_i;
   char *img_comp, *img_csp;
   unsigned char *idata1, *idata2;
   int ilen1, iw1, ih1, id1;
   double ppmm;
   int ilen2, iw2, ih2, id2, ppi, lossyflag;
   IMG_DAT *img_dat;
   int hor_sampfctr[MAX_CMPNTS], vrt_sampfctr[MAX_CMPNTS];
   int n_cmpnts;

   /* If image record index is out of range ... */
   if((imgrecord_i < 1) || (imgrecord_i > ansi_nist->num_records)){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "record index [%d] out of range [1..%d]\n",
              imgrecord_i+1, ansi_nist->num_records+1);
      return(-2);
   }

   /* Set image record pointer. */
   imgrecord = ansi_nist->records[imgrecord_i];

   /* If NOT Type-10,13,14,15,16 ... */
   if(tagged_image_record(ansi_nist->records[imgrecord_i]->type) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "record index [%d] [Type-%d] is not a tagged file image record\n",
              imgrecord_i+1, imgrecord->type);
      return(-3);
   }

   /* 1. Determine Compression */
   /* Lookup grayscale compression algorithm (TAG_CA_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, TAG_CA_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "TAG_CA field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, TAG_CA_ID);
      return(-4);
   }
   img_comp = (char *)field->subfields[0]->items[0]->value;

   /* 2. Determine image W */
   /* Lookup horizontal line length (HLL_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, HLL_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "HLL field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, HLL_ID);
      return(-5);
   }
   iw1 = atoi((char *)field->subfields[0]->items[0]->value);

   /* 3. Determine image H */
   /* Lookup vertical line length (VLL_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, VLL_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "VLL field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, VLL_ID);
      return(-6);
   }
   ih1 = atoi((char *)field->subfields[0]->items[0]->value);

   /* 4. Determine pixel depth */
   /* Lookup bits per pixel or colorspace (BPX_ID==CSP_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, BPX_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "BPX field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, BPX_ID);
      return(-7);
   }
   /* if Type-10 & 17... */
   if((imgrecord->type == TYPE_10_ID) || (imgrecord->type == TYPE_17_ID)){
      if (imgrecord->type == TYPE_10_ID){
      /* Grayscale? CSP_ID = 12, "GRAY" */
         if(lookup_ANSI_NIST_field(&field, &field_i, CSP_ID, imgrecord) == 0){
            fprintf(stderr, "ERROR : dpyan2k_tagged_record : "
		    "CSP field in record index [%d] [Type-%d.%03d] not found\n",
                    imgrecord_i+1, imgrecord->type, CSP_ID);
            return(-2);  
         }               
      }     
      if (imgrecord->type == TYPE_17_ID){
      /* Grayscale? CSP_ID_Type_17 = 13, "GRAY" */
         if(lookup_ANSI_NIST_field(&field, &field_i, CSP_ID_Type_17, imgrecord)
	    == 0){
            fprintf(stderr, "ERROR : dpyan2k_tagged_record : "
		    "CSP field in record index [%d] [Type-%d.%03d] not found\n",
                    imgrecord_i+1, imgrecord->type, CSP_ID_Type_17);
            return(-2);
         } 
      }    

      img_csp = (char *)field->subfields[0]->items[0]->value;
      if(strcmp(img_csp, CSP_GRAY) == 0)
         /* Set grayscale image attributes. */
         id1 = 8;
      else if((strcmp(img_csp, CSP_RGB) == 0) || 
              (strcmp(img_csp, CSP_YCC) == 0) ||
              (strcmp(img_csp, CSP_SRGB) == 0) ||
              (strcmp(img_csp, CSP_SYCC) == 0))
         /* Set color image attributes. */
         id1 = 24;
      /* Otherwise, unsupported color space, so ignore image record. */
      else{
         fprintf(stderr, "WARNING : decode_tagged_field_image : "
		 "colorspace \"%.10s%s\" not supported in "
		 "in record [%d] [Type-%d.%03d].\n"
		 "Image record ignored.\n", 
		 img_csp, strlen(img_csp) > 10 ? "..." : "",
		 imgrecord_i+1, imgrecord->type, CSP_ID);
         return(FALSE);
      }
   }
   /* Otherwise, Type-13,14,15,16 ... so current value == BPX_ID. */
   else{
      /* Set image pixel depth = BPX_ID. */
      id1 = atoi((char *)field->subfields[0]->items[0]->value);
   }

   /* 5. Determine ppmm */
   /* Lookup image record's pixel/mm scan resolution. */
   ret = lookup_tagged_field_image_ppmm(&ppmm, imgrecord);
   /* If error or IGNORE ... */
   if(ret <= 0)
      return(ret);

   /* Set image pointer to last field value in record. */
   field = imgrecord->fields[imgrecord->num_fields-1];
   idata1 = field->subfields[0]->items[0]->value;
   ilen1 = field->subfields[0]->items[0]->num_bytes;

   /* If the image data is uncompressed ... */
   if(strcmp(img_comp, COMP_NONE) == 0){
      idata2 = (unsigned char *)malloc((size_t)ilen1);
      if(idata2 == NULL){
         fprintf(stderr, "ERROR : decode_tagged_field_image : "
		 "malloc : idata2 (%d bytes)\n", ilen1);
         return(-8);
      }
      memcpy(idata2, idata1, (size_t)ilen1);

      /* For uncompressed RGB, the ANSI/NIST Standard dictates that */
      /* the pixels will be stored noninterleaved in 3 separate     */
      /* component planes. */
      /* So, if flag set to interleaved ... */
      if((id1 == 24) && (intrlvflag != 0)){
         /* There is no downsampling of RGB planes. */
         n_cmpnts = 3;
         for(i = 0; i < n_cmpnts; i++){
            hor_sampfctr[i] = 1;
            vrt_sampfctr[i] = 1;
         }
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2, iw1, ih1, id1,
				  hor_sampfctr, vrt_sampfctr, n_cmpnts)) != 0){
            free(idata2);
            return(ret);
         }
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }

      *odata = idata2;
      *ow = iw1;
      *oh = ih1;
      *od = id1;
      *oppmm = ppmm;

      return(TRUE);
   }
   /* If WSQ compressed ... */
   else if(strcmp(img_comp, COMP_WSQ) == 0){
      if((ret = wsq_decode_mem(&idata2, &iw2, &ih2, &id2, &ppi, &lossyflag,
                              idata1, ilen1)) != 0)
         return(ret);
   }
#if 0
   /* If JPEGB compressed ... */
   else if(strcmp(img_comp, COMP_JPEGB) == 0){
      if((ret = jpegb_decode_mem(&idata2, &iw2, &ih2, &id2, &ppi, &lossyflag,
                                 idata1, ilen1)) != 0)
         return(ret);
      /* For 3 component color, JPEGB's decoder returns interleaved RGB. */
      /* So, if flag set to NOT interleaved ... */
      if((id2 == 24) && (intrlvflag == 0)){
         /* There is no downsampling of RGB planes. */
         n_cmpnts = 3;
         for(i = 0; i < n_cmpnts; i++){
            hor_sampfctr[i] = 1;
            vrt_sampfctr[i] = 1;
         }
         if((ret = intrlv2not_mem(&idata1, &ilen1, idata2, iw2, ih2, id2,
                                 hor_sampfctr, vrt_sampfctr, n_cmpnts)) != 0){
            free(idata2);
            return(ret);
         }
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
#if 0
   /* If JPEGL compressed ... */
   else if(strcmp(img_comp, COMP_JPEGL) == 0){
      if((ret = jpegl_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, JPEGL's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         /* Note that this is set up to handle downsampled Cb and Cr planes */
         /* if the units encoded were in the YCbCr color space.  However    */
         /* the color space would need to be converted to RGB upon return   */
         /* of this routine. */
         /* The operational assumption is that the encoded color space */
         /* was RGB. */
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                 img_dat->max_width, img_dat->max_height,
                                 img_dat->pix_depth, img_dat->hor_sampfctr,
                                 img_dat->vrt_sampfctr, img_dat->n_cmpnts)) !=0){
            free_IMG_DAT(img_dat, FREE_IMAGE);
            free(idata2);
            return(ret);
         }

         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
      free_IMG_DAT(img_dat, FREE_IMAGE);
   }
#endif
#if 0 /*__NBIS_JASPER__*/
   /* If JPEG2K compress ... */
   else if((strcmp(img_comp, COMP_JPEG2K) == 0) || 
           (strcmp(img_comp, COMP_JPEG2KL) == 0)){
      /* JPEG2K decoder always return 3 components planes. */
      /* id1 = 24; -- What's in the record has already been copied
	              into id1, and it isn't necessarily 24 - jck */
 
      if((ret = jpeg2k_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
  
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, JPEG2K's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                  img_dat->max_width, img_dat->max_height,
                                  img_dat->pix_depth, img_dat->hor_sampfctr,
                                  img_dat->vrt_sampfctr, img_dat->n_cmpnts)) != 0){
            free_IMG_DAT(img_dat, FREE_IMAGE);
            free(idata2);
            return(ret);

         }
         free_IMG_DAT(img_dat, FREE_IMAGE);
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
#if 0 /*__NBIS_OPENJPEG__*/
   /* If JPEG2K compress ... */
   else if((strcmp(img_comp, COMP_JPEG2K) == 0) ||
           (strcmp(img_comp, COMP_JPEG2KL) == 0)){
      /* JPEG2K decoder always return 3 components planes. */
      /* id1 = 24; -- What's in the record has already been copied
                      into id1, and it isn't necessarily 24 - jck */

      if((ret = openjpeg2k_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
 
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, JPEG2K's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                  img_dat->max_width, img_dat->max_height,
                                  img_dat->pix_depth, img_dat->hor_sampfctr,
                                  img_dat->vrt_sampfctr, img_dat->n_cmpnts)) != 0){
            free_IMG_DAT(img_dat, FREE_IMAGE);
            free(idata2);
            return(ret);

         }
         free_IMG_DAT(img_dat, FREE_IMAGE);
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
#if 0 /*__NBIS_PNG__*/
   /* If PNG compressed ... */
   else if(strcmp(img_comp, COMP_PNG) == 0){
      if((ret = png_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, PNG's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                  img_dat->max_width, img_dat->max_height,
                                  img_dat->pix_depth, img_dat->hor_sampfctr,
                                  img_dat->vrt_sampfctr, img_dat->n_cmpnts)) !=  0){
            free_IMG_DAT(img_dat, FREE_IMAGE); 
            free(idata2);
            return(ret);
         }
         free_IMG_DAT(img_dat, FREE_IMAGE);
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
   /* Otherwise, unsupported compression algorithm. */
   else{
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "unsupported compression algorithm %.10s%s in "
	      "image record index [%d] [Type-%d].\n"
	      "Image record ignored.\n",
              img_comp, strlen(img_comp) > 10 ? "..." : "",
              imgrecord_i+1, imgrecord->type);
      /* Ignore image record ... */
      return(FALSE);
   }

   /* Code change by MDG on 07/02/04 to handle discrepancies in   */
   /* image records where the values in fields HLL and VLL differ */
   /* from what was actually decoded from the compressed image    */
   /* block.  In these cases, we post a warning and then set      */
   /* image attributes to be consistent with what was decoded.    */
   if(iw1 != iw2){
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "[HLL field (from file) = %d] != "
	      "[image width (from decoder) = %d]\n"
	      "Will continue with operating assumption "
	      "that image width is %d\n", iw1, iw2, iw2);
      iw1 = iw2;
   }
   if(ih1 != ih2){
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "[VLL field (from file) = %d] != "
	      "[image height (from decoder) = %d]\n"
	      "Will continue with operating assumption "
	      "that image height is %d\n", ih1, ih2, ih2);
      ih1 = ih2;
   }
   if(id1 != id2){
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "[pixel depth (from field value) = %d] != "
	      "[pixel depth (from decoder) = %d]\n"
	      "Will continue with operating assumption "
	      "that image depth is %d\n", id1, id2, id2);
      id1 = id2;
   }

   *odata = idata2;
   *ow = iw1;
   *oh = ih1;
   *od = id1;
   *oppmm = ppmm;

   return(TRUE);
}
コード例 #2
0
ファイル: sd_rfmt.c プロジェクト: Booley/nbis
int main(int argc, char **argv)
{
   int ret, sd_id;
   char *outext, *ifile, ofile[MAXPATHLEN];
   FILE *infp;
   IHEAD *ihead;
   int width, height, depth, ppi;
   unsigned char *tidata, *idata, *odata, *ocdata;
   int i, complen, olen, oclen;
   IMG_DAT *img_dat;
   NISTCOM *nistcom;
   char *comment_text;
   int sampfctr;

   procargs(argc, argv, &sd_id, &outext, &ifile);

   infp = fopen(ifile, "rb");
   if(infp == (FILE *)NULL) {
      fprintf(stderr, "Error opening file %s for reading\n", ifile);
      exit(-2);
   }

   ihead = readihdr(infp);
   if(ihead == (IHEAD *)NULL) {
      fprintf(stderr, "Error reading IHEAD header\n");
      exit(-3);
   }

   sscanf(ihead->height,"%d", &height);
   sscanf(ihead->width,"%d", &width);
   sscanf(ihead->depth,"%d", &depth);
   sscanf(ihead->density,"%d", &ppi);
   sscanf(ihead->complen,"%d", &complen);

   /* Construct NISTCOM */
   if((ret = sd_ihead_to_nistcom(&nistcom, ihead, sd_id))){
      free(ihead);
      exit(ret);
   }
   free(ihead);
   if(sd_id == 14){
      if((ret = combine_wsq_nistcom(&nistcom, width, height, depth, ppi,
                                   1, -1.0 /* unknown bitrate */))){
         freefet(nistcom);
         exit(ret);
      }
   }
   else{
      if((ret = combine_jpegl_nistcom(&nistcom, width, height, depth, ppi,
                                   0, 1, (int *)NULL, (int *)NULL, 0, PRED4))){
         freefet(nistcom);
         exit(ret);
      }
   }

   /* Convert NISTCOM to string. */
   if((ret = fet2string(&comment_text, nistcom))){
      freefet(nistcom);
      exit(ret);
   }
   freefet(nistcom);

   /* Switch on converter, supplying a NISTCOM ... */
   /* If SD14 ... WSQ convert. */
   if(sd_id == 14){
      /* Convert image data to new format in memory. */
      if((ret = wsq14_2_wsq(&odata, &olen, infp))) {
         fclose(infp);
         free(comment_text);
         exit(ret);
      }
      fclose(infp);
      /* Add comment text into new data format stream. */
      if((ret = add_comment_wsq(&ocdata, &oclen, odata, olen,
                                (unsigned char *)comment_text))){
         free(odata);
         free(comment_text);
         exit(ret);
      }
      free(odata);
      odata = ocdata;
      olen = oclen;
   }
   /* Otherwise, SD 4,9,10,18 ... JPEGL convert. */
   else{
      if((tidata = (unsigned char *)malloc(complen)) == (unsigned char *)NULL){
         fprintf(stderr, "ERROR : %s : malloc : tidata\n", argv[0]);
         exit(-4);
      }

      i = fread(tidata, sizeof(unsigned char), complen, infp);
      if(i != complen) {
         fprintf(stderr, "Error reading compressed data from %s\n", ifile);
         free(tidata);
         exit(-5);
      }
      fclose(infp);

      if(debug > 0)
         fprintf(stdout, "File %s read\n", ifile);

      if((idata = (unsigned char *)malloc(width*height))==(unsigned char *)NULL){
         fprintf(stderr, "ERROR : %s : malloc : idata\n", argv[0]);
         free(tidata);
         free(comment_text);
         exit(-6);
      }

      if((ret = jpegl_sd4_decode_mem(tidata, complen,
                                    width, height, depth, idata))){
         free(tidata);
         free(comment_text);
         free(idata);
         exit(ret);
      }
      free(tidata);
      if(debug > 0){
         fprintf(stdout, "Done decode JPEGL SD4 image\n");
         fprintf(stdout, "Starting JPEGL compression\n");
      }

      /* Used to setup integer array of length 1 initialized to 1. */
      sampfctr = 1;
      if((ret = setup_IMG_DAT_nonintrlv_encode(&img_dat, idata,
                                       width, height, depth, ppi,
                                       &sampfctr, &sampfctr, 1,
                                       0, PRED4))) {
         free(comment_text);
         free(idata);
         exit(ret);
      }

      if(debug > 0)
         fprintf(stdout, "Image structure initialized\n");

      if((ret = jpegl_encode_mem(&odata, &olen, img_dat, comment_text))){
         free(comment_text);
         free_IMG_DAT(img_dat, FREE_IMAGE);
         exit(ret);
      }
      free(comment_text);
      free_IMG_DAT(img_dat, FREE_IMAGE);
   }

   if(debug > 0)
      fprintf(stdout, "Image data converted, reformatted byte length = %d\n",
              olen);

   /* Write reformatted file. */

   fileroot(ifile);
   sprintf(ofile, "%s.%s", ifile, outext);

   if((ret = write_raw_from_memsize(ofile, odata, olen))){
      free(odata);
      exit(ret);
   }

   if(debug > 0)
      fprintf(stdout, "Image data written to file %s\n", ofile);

   free(odata);
   exit(0);
}